зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1299435 - part 4 - update Skia source to m55. r=mchang
MozReview-Commit-ID: 8TA6Lovdc28 --HG-- rename : gfx/skia/skia/src/animator/SkCondensedDebug.cpp => gfx/skia/skia/src/animator/SkCondensedDebug.inc rename : gfx/skia/skia/src/animator/SkCondensedRelease.cpp => gfx/skia/skia/src/animator/SkCondensedRelease.inc
This commit is contained in:
Родитель
1509100554
Коммит
97e509997e
|
@ -21,7 +21,6 @@ class SkBitmapRegionDecoder {
|
|||
public:
|
||||
|
||||
enum Strategy {
|
||||
kCanvas_Strategy, // Draw to the canvas, uses SkCodec
|
||||
kAndroidCodec_Strategy, // Uses SkAndroidCodec for scaling and subsetting
|
||||
};
|
||||
|
||||
|
@ -30,8 +29,7 @@ public:
|
|||
* @param strategy Strategy used for scaling and subsetting
|
||||
* @return Tries to create an SkBitmapRegionDecoder, returns NULL on failure
|
||||
*/
|
||||
static SkBitmapRegionDecoder* Create(
|
||||
SkData* data, Strategy strategy);
|
||||
static SkBitmapRegionDecoder* Create(sk_sp<SkData>, Strategy strategy);
|
||||
|
||||
/*
|
||||
* @param stream Takes ownership of the stream
|
||||
|
|
|
@ -23,8 +23,20 @@
|
|||
#define SK_C_PLUS_PLUS_END_GUARD
|
||||
#endif
|
||||
|
||||
#ifndef SK_API
|
||||
#define SK_API
|
||||
#if !defined(SK_API)
|
||||
#if defined(SKIA_DLL)
|
||||
#if defined(_MSC_VER)
|
||||
#if SKIA_IMPLEMENTATION
|
||||
#define SK_API __declspec(dllexport)
|
||||
#else
|
||||
#define SK_API __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define SK_API __attribute__((visibility("default")))
|
||||
#endif
|
||||
#else
|
||||
#define SK_API
|
||||
#endif
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -37,10 +37,11 @@ public:
|
|||
*
|
||||
* The SkPngChunkReader handles unknown chunks in PNGs.
|
||||
* See SkCodec.h for more details.
|
||||
*
|
||||
* Will take a ref if it returns a codec, else will not affect the data.
|
||||
*/
|
||||
static SkAndroidCodec* NewFromData(SkData*, SkPngChunkReader* = NULL);
|
||||
static SkAndroidCodec* NewFromData(sk_sp<SkData>, SkPngChunkReader* = NULL);
|
||||
static SkAndroidCodec* NewFromData(SkData* data, SkPngChunkReader* reader) {
|
||||
return NewFromData(sk_ref_sp(data), reader);
|
||||
}
|
||||
|
||||
virtual ~SkAndroidCodec() {}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "../private/SkTemplates.h"
|
||||
#include "SkColor.h"
|
||||
#include "SkEncodedFormat.h"
|
||||
#include "SkEncodedInfo.h"
|
||||
#include "SkImageInfo.h"
|
||||
#include "SkSize.h"
|
||||
#include "SkStream.h"
|
||||
|
@ -22,6 +23,12 @@ class SkData;
|
|||
class SkPngChunkReader;
|
||||
class SkSampler;
|
||||
|
||||
namespace DM {
|
||||
class CodecSrc;
|
||||
class ColorCodecSrc;
|
||||
}
|
||||
class ColorCodecBench;
|
||||
|
||||
/**
|
||||
* Abstraction layer directly on top of an image codec.
|
||||
*/
|
||||
|
@ -88,10 +95,11 @@ public:
|
|||
* failure to decode the image.
|
||||
* If the PNG does not contain unknown chunks, the SkPngChunkReader
|
||||
* will not be used or modified.
|
||||
*
|
||||
* Will take a ref if it returns a codec, else will not affect the data.
|
||||
*/
|
||||
static SkCodec* NewFromData(SkData*, SkPngChunkReader* = NULL);
|
||||
static SkCodec* NewFromData(sk_sp<SkData>, SkPngChunkReader* = NULL);
|
||||
static SkCodec* NewFromData(SkData* data, SkPngChunkReader* reader) {
|
||||
return NewFromData(sk_ref_sp(data), reader);
|
||||
}
|
||||
|
||||
virtual ~SkCodec();
|
||||
|
||||
|
@ -100,12 +108,7 @@ public:
|
|||
*/
|
||||
const SkImageInfo& getInfo() const { return fSrcInfo; }
|
||||
|
||||
/**
|
||||
* Returns the color space associated with the codec.
|
||||
* Does not affect ownership.
|
||||
* Might be NULL.
|
||||
*/
|
||||
SkColorSpace* getColorSpace() const { return fColorSpace.get(); }
|
||||
const SkEncodedInfo& getEncodedInfo() const { return fEncodedInfo; }
|
||||
|
||||
enum Origin {
|
||||
kTopLeft_Origin = 1, // Default
|
||||
|
@ -250,8 +253,8 @@ public:
|
|||
* If the EncodedFormat is kWEBP_SkEncodedFormat (the only one which
|
||||
* currently supports subsets), the top and left values must be even.
|
||||
*
|
||||
* In getPixels, we will attempt to decode the exact rectangular
|
||||
* subset specified by fSubset.
|
||||
* In getPixels and incremental decode, we will attempt to decode the
|
||||
* exact rectangular subset specified by fSubset.
|
||||
*
|
||||
* In a scanline decode, it does not make sense to specify a subset
|
||||
* top or subset height, since the client already controls which rows
|
||||
|
@ -284,6 +287,12 @@ public:
|
|||
* to scale. If the generator cannot perform this scale,
|
||||
* it will return kInvalidScale.
|
||||
*
|
||||
* If the info contains a non-null SkColorSpace, the codec
|
||||
* will perform the appropriate color space transformation.
|
||||
* If the caller passes in the same color space that was
|
||||
* reported by the codec, the color space transformation is
|
||||
* a no-op.
|
||||
*
|
||||
* If info is kIndex8_SkColorType, then the caller must provide storage for up to 256
|
||||
* SkPMColor values in ctable. On success the generator must copy N colors into that storage,
|
||||
* (where N is the logical number of table entries) and set ctableCount to N.
|
||||
|
@ -345,6 +354,67 @@ public:
|
|||
return this->onGetYUV8Planes(sizeInfo, planes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare for an incremental decode with the specified options.
|
||||
*
|
||||
* This may require a rewind.
|
||||
*
|
||||
* @param dstInfo Info of the destination. If the dimensions do not match
|
||||
* those of getInfo, this implies a scale.
|
||||
* @param dst Memory to write to. Needs to be large enough to hold the subset,
|
||||
* if present, or the full image as described in dstInfo.
|
||||
* @param options Contains decoding options, including if memory is zero
|
||||
* initialized and whether to decode a subset.
|
||||
* @param ctable A pointer to a color table. When dstInfo.colorType() is
|
||||
* kIndex8, this should be non-NULL and have enough storage for 256
|
||||
* colors. The color table will be populated after decoding the palette.
|
||||
* @param ctableCount A pointer to the size of the color table. When
|
||||
* dstInfo.colorType() is kIndex8, this should be non-NULL. It will
|
||||
* be modified to the true size of the color table (<= 256) after
|
||||
* decoding the palette.
|
||||
* @return Enum representing success or reason for failure.
|
||||
*/
|
||||
Result startIncrementalDecode(const SkImageInfo& dstInfo, void* dst, size_t rowBytes,
|
||||
const SkCodec::Options*, SkPMColor* ctable, int* ctableCount);
|
||||
|
||||
Result startIncrementalDecode(const SkImageInfo& dstInfo, void* dst, size_t rowBytes,
|
||||
const SkCodec::Options* options) {
|
||||
return this->startIncrementalDecode(dstInfo, dst, rowBytes, options, nullptr, nullptr);
|
||||
}
|
||||
|
||||
Result startIncrementalDecode(const SkImageInfo& dstInfo, void* dst, size_t rowBytes) {
|
||||
return this->startIncrementalDecode(dstInfo, dst, rowBytes, nullptr, nullptr, nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start/continue the incremental decode.
|
||||
*
|
||||
* Not valid to call before calling startIncrementalDecode().
|
||||
*
|
||||
* After the first call, should only be called again if more data has been
|
||||
* provided to the source SkStream.
|
||||
*
|
||||
* Unlike getPixels and getScanlines, this does not do any filling. This is
|
||||
* left up to the caller, since they may be skipping lines or continuing the
|
||||
* decode later. In the latter case, they may choose to initialize all lines
|
||||
* first, or only initialize the remaining lines after the first call.
|
||||
*
|
||||
* @param rowsDecoded Optional output variable returning the total number of
|
||||
* lines initialized. Only meaningful if this method returns kIncompleteInput.
|
||||
* Otherwise the implementation may not set it.
|
||||
* Note that some implementations may have initialized this many rows, but
|
||||
* not necessarily finished those rows (e.g. interlaced PNG). This may be
|
||||
* useful for determining what rows the client needs to initialize.
|
||||
* @return kSuccess if all lines requested in startIncrementalDecode have
|
||||
* been completely decoded. kIncompleteInput otherwise.
|
||||
*/
|
||||
Result incrementalDecode(int* rowsDecoded = nullptr) {
|
||||
if (!fStartedIncrementalDecode) {
|
||||
return kInvalidParameters;
|
||||
}
|
||||
return this->onIncrementalDecode(rowsDecoded);
|
||||
}
|
||||
|
||||
/**
|
||||
* The remaining functions revolve around decoding scanlines.
|
||||
*/
|
||||
|
@ -465,17 +535,6 @@ public:
|
|||
* Interlaced gifs are an example.
|
||||
*/
|
||||
kOutOfOrder_SkScanlineOrder,
|
||||
|
||||
/*
|
||||
* Indicates that the entire image must be decoded in order to output
|
||||
* any amount of scanlines. In this case, it is a REALLY BAD IDEA to
|
||||
* request scanlines 1-by-1 or in small chunks. The client should
|
||||
* determine which scanlines are needed and ask for all of them in
|
||||
* a single call to getScanlines().
|
||||
*
|
||||
* Interlaced pngs are an example.
|
||||
*/
|
||||
kNone_SkScanlineOrder,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -511,11 +570,22 @@ protected:
|
|||
/**
|
||||
* Takes ownership of SkStream*
|
||||
*/
|
||||
SkCodec(const SkImageInfo&,
|
||||
SkCodec(int width,
|
||||
int height,
|
||||
const SkEncodedInfo&,
|
||||
SkStream*,
|
||||
sk_sp<SkColorSpace> = nullptr,
|
||||
Origin = kTopLeft_Origin);
|
||||
|
||||
/**
|
||||
* Takes ownership of SkStream*
|
||||
* Allows the subclass to set the recommended SkImageInfo
|
||||
*/
|
||||
SkCodec(const SkEncodedInfo&,
|
||||
const SkImageInfo&,
|
||||
SkStream*,
|
||||
Origin = kTopLeft_Origin);
|
||||
|
||||
virtual SkISize onGetScaledDimensions(float /*desiredScale*/) const {
|
||||
// By default, scaling is not supported.
|
||||
return this->getInfo().dimensions();
|
||||
|
@ -581,30 +651,30 @@ protected:
|
|||
* On an incomplete input, getPixels() and getScanlines() will fill any uninitialized
|
||||
* scanlines. This allows the subclass to indicate what value to fill with.
|
||||
*
|
||||
* @param colorType Destination color type.
|
||||
* @param dstInfo Describes the destination.
|
||||
* @return The value with which to fill uninitialized pixels.
|
||||
*
|
||||
* Note that we can interpret the return value as an SkPMColor, a 16-bit 565 color,
|
||||
* an 8-bit gray color, or an 8-bit index into a color table, depending on the color
|
||||
* type.
|
||||
* Note that we can interpret the return value as a 64-bit Float16 color, a SkPMColor,
|
||||
* a 16-bit 565 color, an 8-bit gray color, or an 8-bit index into a color table,
|
||||
* depending on the color type.
|
||||
*/
|
||||
uint32_t getFillValue(SkColorType colorType) const {
|
||||
return this->onGetFillValue(colorType);
|
||||
uint64_t getFillValue(const SkImageInfo& dstInfo) const {
|
||||
return this->onGetFillValue(dstInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Some subclasses will override this function, but this is a useful default for the color
|
||||
* types that we support. Note that for color types that do not use the full 32-bits,
|
||||
* types that we support. Note that for color types that do not use the full 64-bits,
|
||||
* we will simply take the low bits of the fill value.
|
||||
*
|
||||
* The defaults are:
|
||||
* kRGBA_F16_SkColorType: Transparent or Black, depending on the src alpha type
|
||||
* kN32_SkColorType: Transparent or Black, depending on the src alpha type
|
||||
* kRGB_565_SkColorType: Black
|
||||
* kGray_8_SkColorType: Black
|
||||
* kIndex_8_SkColorType: First color in color table
|
||||
*/
|
||||
virtual uint32_t onGetFillValue(SkColorType /*colorType*/) const {
|
||||
return kOpaque_SkAlphaType == fSrcInfo.alphaType() ? SK_ColorBLACK : SK_ColorTRANSPARENT;
|
||||
}
|
||||
virtual uint64_t onGetFillValue(const SkImageInfo& dstInfo) const;
|
||||
|
||||
/**
|
||||
* Get method for the input stream
|
||||
|
@ -622,11 +692,6 @@ protected:
|
|||
*/
|
||||
virtual SkScanlineOrder onGetScanlineOrder() const { return kTopDown_SkScanlineOrder; }
|
||||
|
||||
/**
|
||||
* Update the current scanline. Used by interlaced png.
|
||||
*/
|
||||
void updateCurrScanline(int newY) { fCurrScanline = newY; }
|
||||
|
||||
const SkImageInfo& dstInfo() const { return fDstInfo; }
|
||||
|
||||
const SkCodec::Options& options() const { return fOptions; }
|
||||
|
@ -641,18 +706,26 @@ protected:
|
|||
|
||||
virtual int onOutputScanline(int inputScanline) const;
|
||||
|
||||
/**
|
||||
* Used for testing with qcms.
|
||||
* FIXME: Remove this when we are done comparing with qcms.
|
||||
*/
|
||||
virtual sk_sp<SkData> getICCData() const { return nullptr; }
|
||||
private:
|
||||
const SkEncodedInfo fEncodedInfo;
|
||||
const SkImageInfo fSrcInfo;
|
||||
SkAutoTDelete<SkStream> fStream;
|
||||
bool fNeedsRewind;
|
||||
sk_sp<SkColorSpace> fColorSpace;
|
||||
const Origin fOrigin;
|
||||
|
||||
// These fields are only meaningful during scanline decodes.
|
||||
SkImageInfo fDstInfo;
|
||||
SkCodec::Options fOptions;
|
||||
|
||||
// Only meaningful during scanline decodes.
|
||||
int fCurrScanline;
|
||||
|
||||
bool fStartedIncrementalDecode;
|
||||
|
||||
/**
|
||||
* Return whether these dimensions are supported as a scale.
|
||||
*
|
||||
|
@ -672,6 +745,16 @@ private:
|
|||
return kUnimplemented;
|
||||
}
|
||||
|
||||
virtual Result onStartIncrementalDecode(const SkImageInfo& /*dstInfo*/, void*, size_t,
|
||||
const SkCodec::Options&, SkPMColor*, int*) {
|
||||
return kUnimplemented;
|
||||
}
|
||||
|
||||
virtual Result onIncrementalDecode(int*) {
|
||||
return kUnimplemented;
|
||||
}
|
||||
|
||||
|
||||
virtual bool onSkipScanlines(int /*countLines*/) { return false; }
|
||||
|
||||
virtual int onGetScanlines(void* /*dst*/, int /*countLines*/, size_t /*rowBytes*/) { return 0; }
|
||||
|
@ -703,6 +786,12 @@ private:
|
|||
*/
|
||||
virtual SkSampler* getSampler(bool /*createIfNecessary*/) { return nullptr; }
|
||||
|
||||
// For testing with qcms
|
||||
// FIXME: Remove these when we are done comparing with qcms.
|
||||
friend class DM::ColorCodecSrc;
|
||||
friend class ColorCodecBench;
|
||||
|
||||
friend class DM::CodecSrc; // for fillIncompleteImage
|
||||
friend class SkSampledCodec;
|
||||
friend class SkIcoCodec;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,199 @@
|
|||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkEncodedInfo_DEFINED
|
||||
#define SkEncodedInfo_DEFINED
|
||||
|
||||
#include "SkImageInfo.h"
|
||||
|
||||
class SkColorSpace;
|
||||
|
||||
struct SkEncodedInfo {
|
||||
public:
|
||||
|
||||
enum Alpha {
|
||||
kOpaque_Alpha,
|
||||
kUnpremul_Alpha,
|
||||
|
||||
// Each pixel is either fully opaque or fully transparent.
|
||||
// There is no difference between requesting kPremul or kUnpremul.
|
||||
kBinary_Alpha,
|
||||
};
|
||||
|
||||
/*
|
||||
* We strive to make the number of components per pixel obvious through
|
||||
* our naming conventions.
|
||||
* Ex: kRGB has 3 components. kRGBA has 4 components.
|
||||
*
|
||||
* This sometimes results in redundant Alpha and Color information.
|
||||
* Ex: kRGB images must also be kOpaque.
|
||||
*/
|
||||
enum Color {
|
||||
// PNG, WBMP
|
||||
kGray_Color,
|
||||
|
||||
// PNG
|
||||
kGrayAlpha_Color,
|
||||
|
||||
// PNG, GIF, BMP
|
||||
kPalette_Color,
|
||||
|
||||
// PNG, RAW
|
||||
kRGB_Color,
|
||||
kRGBA_Color,
|
||||
|
||||
// BMP
|
||||
kBGR_Color,
|
||||
kBGRX_Color,
|
||||
kBGRA_Color,
|
||||
|
||||
// JPEG, WEBP
|
||||
kYUV_Color,
|
||||
|
||||
// WEBP
|
||||
kYUVA_Color,
|
||||
|
||||
// JPEG
|
||||
// Photoshop actually writes inverted CMYK data into JPEGs, where zero
|
||||
// represents 100% ink coverage. For this reason, we treat CMYK JPEGs
|
||||
// as having inverted CMYK. libjpeg-turbo warns that this may break
|
||||
// other applications, but the CMYK JPEGs we see on the web expect to
|
||||
// be treated as inverted CMYK.
|
||||
kInvertedCMYK_Color,
|
||||
kYCCK_Color,
|
||||
};
|
||||
|
||||
static SkEncodedInfo Make(Color color, Alpha alpha, int bitsPerComponent) {
|
||||
SkASSERT(1 == bitsPerComponent ||
|
||||
2 == bitsPerComponent ||
|
||||
4 == bitsPerComponent ||
|
||||
8 == bitsPerComponent ||
|
||||
16 == bitsPerComponent);
|
||||
|
||||
switch (color) {
|
||||
case kGray_Color:
|
||||
SkASSERT(kOpaque_Alpha == alpha);
|
||||
break;
|
||||
case kGrayAlpha_Color:
|
||||
SkASSERT(kOpaque_Alpha != alpha);
|
||||
break;
|
||||
case kPalette_Color:
|
||||
SkASSERT(16 != bitsPerComponent);
|
||||
break;
|
||||
case kRGB_Color:
|
||||
case kBGR_Color:
|
||||
case kBGRX_Color:
|
||||
SkASSERT(kOpaque_Alpha == alpha);
|
||||
SkASSERT(bitsPerComponent >= 8);
|
||||
break;
|
||||
case kYUV_Color:
|
||||
case kInvertedCMYK_Color:
|
||||
case kYCCK_Color:
|
||||
SkASSERT(kOpaque_Alpha == alpha);
|
||||
SkASSERT(8 == bitsPerComponent);
|
||||
break;
|
||||
case kRGBA_Color:
|
||||
SkASSERT(kOpaque_Alpha != alpha);
|
||||
SkASSERT(bitsPerComponent >= 8);
|
||||
break;
|
||||
case kBGRA_Color:
|
||||
case kYUVA_Color:
|
||||
SkASSERT(kOpaque_Alpha != alpha);
|
||||
SkASSERT(8 == bitsPerComponent);
|
||||
break;
|
||||
default:
|
||||
SkASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
return SkEncodedInfo(color, alpha, bitsPerComponent);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns an SkImageInfo with Skia color and alpha types that are the
|
||||
* closest possible match to the encoded info.
|
||||
*/
|
||||
SkImageInfo makeImageInfo(int width, int height, sk_sp<SkColorSpace> colorSpace) const {
|
||||
switch (fColor) {
|
||||
case kGray_Color:
|
||||
SkASSERT(kOpaque_Alpha == fAlpha);
|
||||
return SkImageInfo::Make(width, height, kGray_8_SkColorType,
|
||||
kOpaque_SkAlphaType, colorSpace);
|
||||
case kGrayAlpha_Color:
|
||||
SkASSERT(kOpaque_Alpha != fAlpha);
|
||||
return SkImageInfo::Make(width, height, kN32_SkColorType,
|
||||
kUnpremul_SkAlphaType, colorSpace);
|
||||
case kPalette_Color: {
|
||||
SkAlphaType alphaType = (kOpaque_Alpha == fAlpha) ? kOpaque_SkAlphaType :
|
||||
kUnpremul_SkAlphaType;
|
||||
return SkImageInfo::Make(width, height, kIndex_8_SkColorType,
|
||||
alphaType, colorSpace);
|
||||
}
|
||||
case kRGB_Color:
|
||||
case kBGR_Color:
|
||||
case kBGRX_Color:
|
||||
case kYUV_Color:
|
||||
case kInvertedCMYK_Color:
|
||||
case kYCCK_Color:
|
||||
SkASSERT(kOpaque_Alpha == fAlpha);
|
||||
return SkImageInfo::Make(width, height, kN32_SkColorType,
|
||||
kOpaque_SkAlphaType, colorSpace);
|
||||
case kRGBA_Color:
|
||||
case kBGRA_Color:
|
||||
case kYUVA_Color:
|
||||
SkASSERT(kOpaque_Alpha != fAlpha);
|
||||
return SkImageInfo::Make(width, height, kN32_SkColorType,
|
||||
kUnpremul_SkAlphaType, std::move(colorSpace));
|
||||
default:
|
||||
SkASSERT(false);
|
||||
return SkImageInfo::MakeUnknown();
|
||||
}
|
||||
}
|
||||
|
||||
Color color() const { return fColor; }
|
||||
Alpha alpha() const { return fAlpha; }
|
||||
uint8_t bitsPerComponent() const { return fBitsPerComponent; }
|
||||
|
||||
uint8_t bitsPerPixel() const {
|
||||
switch (fColor) {
|
||||
case kGray_Color:
|
||||
return fBitsPerComponent;
|
||||
case kGrayAlpha_Color:
|
||||
return 2 * fBitsPerComponent;
|
||||
case kPalette_Color:
|
||||
return fBitsPerComponent;
|
||||
case kRGB_Color:
|
||||
case kBGR_Color:
|
||||
case kYUV_Color:
|
||||
return 3 * fBitsPerComponent;
|
||||
case kRGBA_Color:
|
||||
case kBGRA_Color:
|
||||
case kBGRX_Color:
|
||||
case kYUVA_Color:
|
||||
case kInvertedCMYK_Color:
|
||||
case kYCCK_Color:
|
||||
return 4 * fBitsPerComponent;
|
||||
default:
|
||||
SkASSERT(false);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
SkEncodedInfo(Color color, Alpha alpha, uint8_t bitsPerComponent)
|
||||
: fColor(color)
|
||||
, fAlpha(alpha)
|
||||
, fBitsPerComponent(bitsPerComponent)
|
||||
{}
|
||||
|
||||
Color fColor;
|
||||
Alpha fAlpha;
|
||||
uint8_t fBitsPerComponent;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -95,7 +95,7 @@
|
|||
|
||||
/* Define this to provide font subsetter in PDF generation.
|
||||
*/
|
||||
//#define SK_SFNTLY_SUBSETTER "sfntly/subsetter/font_subsetter.h"
|
||||
//#define SK_SFNTLY_SUBSETTER "sample/chromium/font_subsetter.h"
|
||||
|
||||
/* Define this to set the upper limit for text to support LCD. Values that
|
||||
are very large increase the cost in the font cache and draw slower, without
|
||||
|
@ -154,6 +154,8 @@
|
|||
|
||||
#define SK_RASTERIZE_EVEN_ROUNDING
|
||||
|
||||
#define SK_DISABLE_SCREENSPACE_TESS_AA_PATH_RENDERER
|
||||
|
||||
#define SK_DISABLE_SLOW_DEBUG_VALIDATION 1
|
||||
|
||||
#define MOZ_SKIA 1
|
||||
|
@ -166,15 +168,4 @@
|
|||
# endif
|
||||
#endif
|
||||
|
||||
/* Check if building with either MSVC, libc++, or a sufficiently recent version of libstdc++.
|
||||
+ * On platforms like OS X 10.6 or older Android SDKs, we need to work around a lack of certain
|
||||
+ * C++11 features.
|
||||
+ */
|
||||
#include "mozilla/Compiler.h"
|
||||
#if MOZ_IS_MSVC || MOZ_USING_LIBCXX || MOZ_LIBSTDCXX_VERSION_AT_LEAST(4, 8, 0)
|
||||
# define MOZ_SKIA_AVOID_CXX11 0
|
||||
#else
|
||||
# define MOZ_SKIA_AVOID_CXX11 1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,7 +18,7 @@ public:
|
|||
* Allocate a new SkBBoxHierarchy. Return NULL on failure.
|
||||
*/
|
||||
virtual SkBBoxHierarchy* operator()(const SkRect& bounds) const = 0;
|
||||
virtual ~SkBBHFactory() {};
|
||||
virtual ~SkBBHFactory() {}
|
||||
};
|
||||
|
||||
class SK_API SkRTreeFactory : public SkBBHFactory {
|
||||
|
|
|
@ -23,7 +23,6 @@ class SkPixelRef;
|
|||
class SkPixelRefFactory;
|
||||
class SkRegion;
|
||||
class SkString;
|
||||
class GrTexture;
|
||||
|
||||
/** \class SkBitmap
|
||||
|
||||
|
@ -85,7 +84,7 @@ public:
|
|||
int height() const { return fInfo.height(); }
|
||||
SkColorType colorType() const { return fInfo.colorType(); }
|
||||
SkAlphaType alphaType() const { return fInfo.alphaType(); }
|
||||
SkColorProfileType profileType() const { return fInfo.profileType(); }
|
||||
SkColorSpace* colorSpace() const { return fInfo.colorSpace(); }
|
||||
|
||||
/**
|
||||
* Return the number of bytes per pixel based on the colortype. If the colortype is
|
||||
|
@ -105,7 +104,7 @@ public:
|
|||
* Return the shift amount per pixel (i.e. 0 for 1-byte per pixel, 1 for 2-bytes per pixel
|
||||
* colortypes, 2 for 4-bytes per pixel colortypes). Return 0 for kUnknown_SkColorType.
|
||||
*/
|
||||
int shiftPerPixel() const { return this->bytesPerPixel() >> 1; }
|
||||
int shiftPerPixel() const { return this->fInfo.shiftPerPixel(); }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -455,6 +454,7 @@ public:
|
|||
* not be used as targets for a raster device/canvas (since all pixels
|
||||
* modifications will be lost when unlockPixels() is called.)
|
||||
*/
|
||||
// DEPRECATED
|
||||
bool lockPixelsAreWritable() const;
|
||||
|
||||
bool requestLock(SkAutoPixmapUnlock* result) const;
|
||||
|
@ -468,10 +468,6 @@ public:
|
|||
(this->colorType() != kIndex_8_SkColorType || fColorTable);
|
||||
}
|
||||
|
||||
/** Returns the pixelRef's texture, or NULL
|
||||
*/
|
||||
GrTexture* getTexture() const;
|
||||
|
||||
/** Return the bitmap's colortable, if it uses one (i.e. colorType is
|
||||
Index_8) and the pixels are locked.
|
||||
Otherwise returns NULL. Does not affect the colortable's
|
||||
|
@ -774,8 +770,8 @@ private:
|
|||
static void WriteRawPixels(SkWriteBuffer*, const SkBitmap&);
|
||||
static bool ReadRawPixels(SkReadBuffer*, SkBitmap*);
|
||||
|
||||
friend class SkReadBuffer; // unflatten, rawpixels
|
||||
friend class SkWriteBuffer; // rawpixels
|
||||
friend class SkReadBuffer; // unflatten, rawpixels
|
||||
friend class SkBinaryWriteBuffer; // rawpixels
|
||||
friend struct SkBitmapProcState;
|
||||
};
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include "SkCanvas.h"
|
||||
#include "SkColor.h"
|
||||
#include "SkDevice.h"
|
||||
#include "SkImageFilter.h"
|
||||
#include "SkImageInfo.h"
|
||||
#include "SkRect.h"
|
||||
#include "SkScalar.h"
|
||||
|
@ -22,6 +21,7 @@
|
|||
#include "SkTypes.h"
|
||||
|
||||
class SkDraw;
|
||||
class SkImageFilterCache;
|
||||
class SkMatrix;
|
||||
class SkPaint;
|
||||
class SkPath;
|
||||
|
@ -58,8 +58,6 @@ public:
|
|||
|
||||
static SkBitmapDevice* Create(const SkImageInfo&, const SkSurfaceProps&);
|
||||
|
||||
SkImageInfo imageInfo() const override;
|
||||
|
||||
protected:
|
||||
bool onShouldDisableLCD(const SkPaint&) const override;
|
||||
|
||||
|
@ -121,6 +119,13 @@ protected:
|
|||
const SkPaint& paint) override;
|
||||
virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y, const SkPaint&) override;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void drawSpecial(const SkDraw&, SkSpecialImage*, int x, int y, const SkPaint&) override;
|
||||
sk_sp<SkSpecialImage> makeSpecial(const SkBitmap&) override;
|
||||
sk_sp<SkSpecialImage> makeSpecial(const SkImage*) override;
|
||||
sk_sp<SkSpecialImage> snapSpecial() override;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Update as needed the pixel value in the bitmap, so that the caller can
|
||||
|
@ -128,7 +133,11 @@ protected:
|
|||
altered. The config/width/height/rowbytes must remain unchanged.
|
||||
@return the device contents as a bitmap
|
||||
*/
|
||||
#ifdef SK_SUPPORT_LEGACY_ACCESSBITMAP
|
||||
const SkBitmap& onAccessBitmap() override;
|
||||
#else
|
||||
const SkBitmap& onAccessBitmap();
|
||||
#endif
|
||||
|
||||
SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
|
||||
// just for subclasses, to assign a custom pixelref
|
||||
|
@ -141,8 +150,6 @@ protected:
|
|||
bool onWritePixels(const SkImageInfo&, const void*, size_t, int, int) override;
|
||||
bool onPeekPixels(SkPixmap*) override;
|
||||
bool onAccessPixels(SkPixmap*) override;
|
||||
void onAttachToCanvas(SkCanvas*) override;
|
||||
void onDetachFromCanvas() override;
|
||||
|
||||
private:
|
||||
friend class SkCanvas;
|
||||
|
@ -162,7 +169,7 @@ private:
|
|||
|
||||
sk_sp<SkSurface> makeSurface(const SkImageInfo&, const SkSurfaceProps&) override;
|
||||
|
||||
SkImageFilter::Cache* getImageFilterCache() override;
|
||||
SkImageFilterCache* getImageFilterCache() override;
|
||||
|
||||
SkBitmap fBitmap;
|
||||
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkBlendMode_DEFINED
|
||||
#define SkBlendMode_DEFINED
|
||||
|
||||
enum class SkBlendMode {
|
||||
kClear, //!< [0, 0]
|
||||
kSrc, //!< [Sa, Sc]
|
||||
kDst, //!< [Da, Dc]
|
||||
kSrcOver, //!< [Sa + Da * (1 - Sa), Sc + Dc * (1 - Sa)]
|
||||
kDstOver, //!< [Da + Sa * (1 - Da), Dc + Sc * (1 - Da)]
|
||||
kSrcIn, //!< [Sa * Da, Sc * Da]
|
||||
kDstIn, //!< [Da * Sa, Dc * Sa]
|
||||
kSrcOut, //!< [Sa * (1 - Da), Sc * (1 - Da)]
|
||||
kDstOut, //!< [Da * (1 - Sa), Dc * (1 - Sa)]
|
||||
kSrcATop, //!< [Da, Sc * Da + Dc * (1 - Sa)]
|
||||
kDstATop, //!< [Sa, Dc * Sa + Sc * (1 - Da)]
|
||||
kXor, //!< [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + Dc * (1 - Sa)]
|
||||
kPlus, //!< [Sa + Da, Sc + Dc]
|
||||
kModulate, // multiplies all components (= alpha and color)
|
||||
|
||||
// Following blend modes are defined in the CSS Compositing standard:
|
||||
// https://dvcs.w3.org/hg/FXTF/rawfile/tip/compositing/index.html#blending
|
||||
kScreen,
|
||||
kLastCoeffMode = kScreen,
|
||||
|
||||
kOverlay,
|
||||
kDarken,
|
||||
kLighten,
|
||||
kColorDodge,
|
||||
kColorBurn,
|
||||
kHardLight,
|
||||
kSoftLight,
|
||||
kDifference,
|
||||
kExclusion,
|
||||
kMultiply,
|
||||
kLastSeparableMode = kMultiply,
|
||||
|
||||
kHue,
|
||||
kSaturation,
|
||||
kColor,
|
||||
kLuminosity,
|
||||
kLastMode = kLuminosity
|
||||
};
|
||||
|
||||
#endif
|
|
@ -9,7 +9,9 @@
|
|||
#define SkCanvas_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
#include "SkBlendMode.h"
|
||||
#include "SkBitmap.h"
|
||||
#include "SkClipOp.h"
|
||||
#include "SkDeque.h"
|
||||
#include "SkImage.h"
|
||||
#include "SkPaint.h"
|
||||
|
@ -17,9 +19,11 @@
|
|||
#include "SkRegion.h"
|
||||
#include "SkSurfaceProps.h"
|
||||
#include "SkXfermode.h"
|
||||
#include "SkLights.h"
|
||||
#include "../private/SkShadowParams.h"
|
||||
|
||||
class GrContext;
|
||||
class GrRenderTarget;
|
||||
class GrDrawContext;
|
||||
class SkBaseDevice;
|
||||
class SkCanvasClipVisitor;
|
||||
class SkClipStack;
|
||||
|
@ -32,12 +36,15 @@ class SkMetaData;
|
|||
class SkPath;
|
||||
class SkPicture;
|
||||
class SkPixmap;
|
||||
class SkRasterClip;
|
||||
class SkRRect;
|
||||
struct SkRSXform;
|
||||
class SkSurface;
|
||||
class SkSurface_Base;
|
||||
class SkTextBlob;
|
||||
|
||||
//#define SK_SUPPORT_LEGACY_CLIP_REGIONOPS
|
||||
|
||||
/** \class SkCanvas
|
||||
|
||||
A Canvas encapsulates all of the state about drawing into a device (bitmap).
|
||||
|
@ -57,8 +64,27 @@ class SK_API SkCanvas : public SkRefCnt {
|
|||
enum PrivateSaveLayerFlags {
|
||||
kDontClipToLayer_PrivateSaveLayerFlag = 1U << 31,
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
#ifdef SK_SUPPORT_LEGACY_CLIP_REGIONOPS
|
||||
typedef SkRegion::Op ClipOp;
|
||||
|
||||
static const ClipOp kDifference_Op = SkRegion::kDifference_Op;
|
||||
static const ClipOp kIntersect_Op = SkRegion::kIntersect_Op;
|
||||
static const ClipOp kUnion_Op = SkRegion::kUnion_Op;
|
||||
static const ClipOp kXOR_Op = SkRegion::kXOR_Op;
|
||||
static const ClipOp kReverseDifference_Op = SkRegion::kReverseDifference_Op;
|
||||
static const ClipOp kReplace_Op = SkRegion::kReplace_Op;
|
||||
#else
|
||||
typedef SkClipOp ClipOp;
|
||||
|
||||
static const ClipOp kDifference_Op = kDifference_SkClipOp;
|
||||
static const ClipOp kIntersect_Op = kIntersect_SkClipOp;
|
||||
static const ClipOp kUnion_Op = kUnion_SkClipOp;
|
||||
static const ClipOp kXOR_Op = kXOR_SkClipOp;
|
||||
static const ClipOp kReverseDifference_Op = kReverseDifference_SkClipOp;
|
||||
static const ClipOp kReplace_Op = kReplace_SkClipOp;
|
||||
#endif
|
||||
/**
|
||||
* Attempt to allocate raster canvas, matching the ImageInfo, that will draw directly into the
|
||||
* specified pixels. To access the pixels after drawing to them, the caller should call
|
||||
|
@ -418,11 +444,18 @@ public:
|
|||
*/
|
||||
void scale(SkScalar sx, SkScalar sy);
|
||||
|
||||
/** Preconcat the current matrix with the specified rotation.
|
||||
/** Preconcat the current matrix with the specified rotation about the origin.
|
||||
@param degrees The amount to rotate, in degrees
|
||||
*/
|
||||
void rotate(SkScalar degrees);
|
||||
|
||||
/** Preconcat the current matrix with the specified rotation about a given point.
|
||||
@param degrees The amount to rotate, in degrees
|
||||
@param px The x coordinate of the point to rotate about.
|
||||
@param py The y coordinate of the point to rotate about.
|
||||
*/
|
||||
void rotate(SkScalar degrees, SkScalar px, SkScalar py);
|
||||
|
||||
/** Preconcat the current matrix with the specified skew.
|
||||
@param sx The amount to skew in X
|
||||
@param sy The amount to skew in Y
|
||||
|
@ -443,15 +476,37 @@ public:
|
|||
*/
|
||||
void resetMatrix();
|
||||
|
||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||
/** Add the specified translation to the current draw depth of the canvas.
|
||||
@param z The distance to translate in Z.
|
||||
Negative into screen, positive out of screen.
|
||||
Without translation, the draw depth defaults to 0.
|
||||
*/
|
||||
void translateZ(SkScalar z);
|
||||
|
||||
/** Set the current set of lights in the canvas.
|
||||
@param lights The lights that we want the canvas to have.
|
||||
*/
|
||||
void setLights(sk_sp<SkLights> lights);
|
||||
|
||||
/** Returns the current set of lights the canvas uses
|
||||
*/
|
||||
sk_sp<SkLights> getLights() const;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Modify the current clip with the specified rectangle.
|
||||
* @param rect The rect to combine with the current clip
|
||||
* @param op The region op to apply to the current clip
|
||||
* @param doAntiAlias true if the clip should be antialiased
|
||||
*/
|
||||
void clipRect(const SkRect& rect,
|
||||
SkRegion::Op op = SkRegion::kIntersect_Op,
|
||||
bool doAntiAlias = false);
|
||||
void clipRect(const SkRect& rect, ClipOp, bool doAntiAlias);
|
||||
void clipRect(const SkRect& rect, ClipOp op) {
|
||||
this->clipRect(rect, op, false);
|
||||
}
|
||||
void clipRect(const SkRect& rect, bool doAntiAlias = false) {
|
||||
this->clipRect(rect, kIntersect_Op, doAntiAlias);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify the current clip with the specified SkRRect.
|
||||
|
@ -459,9 +514,13 @@ public:
|
|||
* @param op The region op to apply to the current clip
|
||||
* @param doAntiAlias true if the clip should be antialiased
|
||||
*/
|
||||
void clipRRect(const SkRRect& rrect,
|
||||
SkRegion::Op op = SkRegion::kIntersect_Op,
|
||||
bool doAntiAlias = false);
|
||||
void clipRRect(const SkRRect& rrect, ClipOp op, bool doAntiAlias);
|
||||
void clipRRect(const SkRRect& rrect, ClipOp op) {
|
||||
this->clipRRect(rrect, op, false);
|
||||
}
|
||||
void clipRRect(const SkRRect& rrect, bool doAntiAlias = false) {
|
||||
this->clipRRect(rrect, kIntersect_Op, doAntiAlias);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify the current clip with the specified path.
|
||||
|
@ -469,16 +528,12 @@ public:
|
|||
* @param op The region op to apply to the current clip
|
||||
* @param doAntiAlias true if the clip should be antialiased
|
||||
*/
|
||||
void clipPath(const SkPath& path,
|
||||
SkRegion::Op op = SkRegion::kIntersect_Op,
|
||||
bool doAntiAlias = false);
|
||||
|
||||
/** EXPERIMENTAL -- only used for testing
|
||||
Set to false to force clips to be hard, even if doAntiAlias=true is
|
||||
passed to clipRect or clipPath.
|
||||
*/
|
||||
void setAllowSoftClip(bool allow) {
|
||||
fAllowSoftClip = allow;
|
||||
void clipPath(const SkPath& path, ClipOp op, bool doAntiAlias);
|
||||
void clipPath(const SkPath& path, ClipOp op) {
|
||||
this->clipPath(path, op, false);
|
||||
}
|
||||
void clipPath(const SkPath& path, bool doAntiAlias = false) {
|
||||
this->clipPath(path, kIntersect_Op, doAntiAlias);
|
||||
}
|
||||
|
||||
/** EXPERIMENTAL -- only used for testing
|
||||
|
@ -495,17 +550,7 @@ public:
|
|||
@param deviceRgn The region to apply to the current clip
|
||||
@param op The region op to apply to the current clip
|
||||
*/
|
||||
void clipRegion(const SkRegion& deviceRgn,
|
||||
SkRegion::Op op = SkRegion::kIntersect_Op);
|
||||
|
||||
/** Helper for clipRegion(rgn, kReplace_Op). Sets the current clip to the
|
||||
specified region. This does not intersect or in any other way account
|
||||
for the existing clip region.
|
||||
@param deviceRgn The region to copy into the current clip.
|
||||
*/
|
||||
void setClipRegion(const SkRegion& deviceRgn) {
|
||||
this->clipRegion(deviceRgn, SkRegion::kReplace_Op);
|
||||
}
|
||||
void clipRegion(const SkRegion& deviceRgn, ClipOp op = kIntersect_Op);
|
||||
|
||||
/** Return true if the specified rectangle, after being transformed by the
|
||||
current matrix, would lie completely outside of the current clip. Call
|
||||
|
@ -529,40 +574,6 @@ public:
|
|||
*/
|
||||
bool quickReject(const SkPath& path) const;
|
||||
|
||||
/** Return true if the horizontal band specified by top and bottom is
|
||||
completely clipped out. This is a conservative calculation, meaning
|
||||
that it is possible that if the method returns false, the band may still
|
||||
in fact be clipped out, but the converse is not true. If this method
|
||||
returns true, then the band is guaranteed to be clipped out.
|
||||
@param top The top of the horizontal band to compare with the clip
|
||||
@param bottom The bottom of the horizontal and to compare with the clip
|
||||
@return true if the horizontal band is completely clipped out (i.e. does
|
||||
not intersect the current clip)
|
||||
*/
|
||||
bool quickRejectY(SkScalar top, SkScalar bottom) const {
|
||||
SkASSERT(top <= bottom);
|
||||
|
||||
#ifndef SK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT
|
||||
// TODO: add a hasPerspective method similar to getLocalClipBounds. This
|
||||
// would cache the SkMatrix::hasPerspective result. Alternatively, have
|
||||
// the MC stack just set a hasPerspective boolean as it is updated.
|
||||
if (this->getTotalMatrix().hasPerspective()) {
|
||||
// TODO: consider implementing some half-plane test between the
|
||||
// two Y planes and the device-bounds (i.e., project the top and
|
||||
// bottom Y planes and then determine if the clip bounds is completely
|
||||
// outside either one).
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
const SkRect& clipR = this->getLocalClipBounds();
|
||||
// In the case where the clip is empty and we are provided with a
|
||||
// negative top and positive bottom parameter then this test will return
|
||||
// false even though it will be clipped. We have chosen to exclude that
|
||||
// check as it is rare and would result double the comparisons.
|
||||
return top >= clipR.fBottom || bottom <= clipR.fTop;
|
||||
}
|
||||
|
||||
/** Return the bounds of the current clip (in local coordinates) in the
|
||||
bounds parameter, and return true if it is non-empty. This can be useful
|
||||
in a way similar to quickReject, in that it tells you that drawing
|
||||
|
@ -585,22 +596,31 @@ public:
|
|||
@param b the blue component (0..255) of the color to fill the canvas
|
||||
@param mode the mode to apply the color in (defaults to SrcOver)
|
||||
*/
|
||||
void drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b,
|
||||
SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode);
|
||||
void drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b, SkBlendMode mode = SkBlendMode::kSrcOver);
|
||||
#ifdef SK_SUPPORT_LEGACY_XFERMODE_OBJECT
|
||||
void drawARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b, SkXfermode::Mode mode) {
|
||||
this->drawARGB(a, r, g, b, (SkBlendMode)mode);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Fill the entire canvas' bitmap (restricted to the current clip) with the
|
||||
specified color and mode.
|
||||
@param color the color to draw with
|
||||
@param mode the mode to apply the color in (defaults to SrcOver)
|
||||
*/
|
||||
void drawColor(SkColor color, SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode);
|
||||
void drawColor(SkColor color, SkBlendMode mode = SkBlendMode::kSrcOver);
|
||||
#ifdef SK_SUPPORT_LEGACY_XFERMODE_OBJECT
|
||||
void drawColor(SkColor color, SkXfermode::Mode mode) {
|
||||
this->drawColor(color, (SkBlendMode)mode);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Helper method for drawing a color in SRC mode, completely replacing all the pixels
|
||||
* in the current clip with this color.
|
||||
*/
|
||||
void clear(SkColor color) {
|
||||
this->drawColor(color, SkXfermode::kSrc_Mode);
|
||||
this->drawColor(color, SkBlendMode::kSrc);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -709,6 +729,12 @@ public:
|
|||
void drawRectCoords(SkScalar left, SkScalar top, SkScalar right,
|
||||
SkScalar bottom, const SkPaint& paint);
|
||||
|
||||
/** Draw the outline of the specified region using the specified paint.
|
||||
@param region The region to be drawn
|
||||
@param paint The paint used to draw the region
|
||||
*/
|
||||
void drawRegion(const SkRegion& region, const SkPaint& paint);
|
||||
|
||||
/** Draw the specified oval using the specified paint. The oval will be
|
||||
filled or framed based on the Style in the paint.
|
||||
@param oval The rectangle bounds of the oval to be drawn
|
||||
|
@ -743,14 +769,17 @@ public:
|
|||
const SkPaint& paint);
|
||||
|
||||
/** Draw the specified arc, which will be scaled to fit inside the
|
||||
specified oval. If the sweep angle is >= 360, then the oval is drawn
|
||||
completely. Note that this differs slightly from SkPath::arcTo, which
|
||||
treats the sweep angle mod 360.
|
||||
@param oval The bounds of oval used to define the shape of the arc
|
||||
specified oval. Sweep angles are not treated as modulo 360 and thus can
|
||||
exceed a full sweep of the oval. Note that this differs slightly from
|
||||
SkPath::arcTo, which treats the sweep angle mod 360. If the oval is empty
|
||||
or the sweep angle is zero nothing is drawn. If useCenter is true the oval
|
||||
center is inserted into the implied path before the arc and the path is
|
||||
closed back to the, center forming a wedge. Otherwise, the implied path
|
||||
contains just the arc and is not closed.
|
||||
@param oval The bounds of oval used to define the shape of the arc.
|
||||
@param startAngle Starting angle (in degrees) where the arc begins
|
||||
@param sweepAngle Sweep angle (in degrees) measured clockwise
|
||||
@param useCenter true means include the center of the oval. For filling
|
||||
this will draw a wedge. False means just use the arc.
|
||||
@param sweepAngle Sweep angle (in degrees) measured clockwise.
|
||||
@param useCenter true means include the center of the oval.
|
||||
@param paint The paint used to draw the arc
|
||||
*/
|
||||
void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
|
||||
|
@ -911,7 +940,7 @@ public:
|
|||
SrcRectConstraint = kStrict_SrcRectConstraint);
|
||||
|
||||
/**
|
||||
* Draw the bitmap stretched differentially to fit into dst.
|
||||
* Draw the bitmap stretched or shrunk differentially to fit into dst.
|
||||
* center is a rect within the bitmap, and logically divides the bitmap
|
||||
* into 9 sections (3x3). For example, if the middle pixel of a [5x5]
|
||||
* bitmap is the "center", then the center-rect should be [2, 2, 3, 3].
|
||||
|
@ -927,6 +956,69 @@ public:
|
|||
void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
|
||||
const SkPaint* paint = NULL);
|
||||
|
||||
/**
|
||||
* Specifies coordinates to divide a bitmap into (xCount*yCount) rects.
|
||||
*
|
||||
* If the lattice divs or bounds are invalid, the entire lattice
|
||||
* struct will be ignored on the draw call.
|
||||
*/
|
||||
struct Lattice {
|
||||
enum Flags : uint8_t {
|
||||
// If set, indicates that we should not draw corresponding rect.
|
||||
kTransparent_Flags = 1 << 0,
|
||||
};
|
||||
|
||||
// An array of x-coordinates that divide the bitmap vertically.
|
||||
// These must be unique, increasing, and in the set [fBounds.fLeft, fBounds.fRight).
|
||||
// Does not have ownership.
|
||||
const int* fXDivs;
|
||||
|
||||
// An array of y-coordinates that divide the bitmap horizontally.
|
||||
// These must be unique, increasing, and in the set [fBounds.fTop, fBounds.fBottom).
|
||||
// Does not have ownership.
|
||||
const int* fYDivs;
|
||||
|
||||
// If non-null, the length of this array must be equal to
|
||||
// (fXCount + 1) * (fYCount + 1). Note that we allow the first rect
|
||||
// in each direction to be empty (ex: fXDivs[0] = fBounds.fLeft).
|
||||
// In this case, the caller still must specify a flag (as a placeholder)
|
||||
// for these empty rects.
|
||||
// The flags correspond to the rects in the lattice, first moving
|
||||
// left to right and then top to bottom.
|
||||
const Flags* fFlags;
|
||||
|
||||
// The number of fXDivs.
|
||||
int fXCount;
|
||||
|
||||
// The number of fYDivs.
|
||||
int fYCount;
|
||||
|
||||
// The bound to draw from. Must be contained by the src that is being drawn,
|
||||
// non-empty, and non-inverted.
|
||||
// If nullptr, the bounds are the entire src.
|
||||
const SkIRect* fBounds;
|
||||
};
|
||||
|
||||
/**
|
||||
* Draw the bitmap stretched or shrunk differentially to fit into dst.
|
||||
*
|
||||
* Moving horizontally across the bitmap, alternating rects will be "scalable"
|
||||
* (in the x-dimension) to fit into dst or must be left "fixed". The first rect
|
||||
* is treated as "fixed", but it's possible to specify an empty first rect by
|
||||
* making lattice.fXDivs[0] = 0.
|
||||
*
|
||||
* The scale factor for all "scalable" rects will be the same, and may be greater
|
||||
* than or less than 1 (meaning we can stretch or shrink). If the number of
|
||||
* "fixed" pixels is greater than the width of the dst, we will collapse all of
|
||||
* the "scalable" regions and appropriately downscale the "fixed" regions.
|
||||
*
|
||||
* The same interpretation also applies to the y-dimension.
|
||||
*/
|
||||
void drawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst,
|
||||
const SkPaint* paint = nullptr);
|
||||
void drawImageLattice(const SkImage* image, const Lattice& lattice, const SkRect& dst,
|
||||
const SkPaint* paint = nullptr);
|
||||
|
||||
/** Draw the text, with origin at (x,y), using the specified paint.
|
||||
The origin is interpreted based on the Align setting in the paint.
|
||||
@param text The text to be drawn
|
||||
|
@ -988,6 +1080,14 @@ public:
|
|||
void drawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
|
||||
const SkMatrix* matrix, const SkPaint& paint);
|
||||
|
||||
/**
|
||||
* Draw the text with each character/glyph individually transformed by its xform.
|
||||
* If cullRect is not null, it is a conservative bounds of what will be drawn
|
||||
* taking into account the xforms and the paint, and will be used to accelerate culling.
|
||||
*/
|
||||
void drawTextRSXform(const void* text, size_t byteLength, const SkRSXform[],
|
||||
const SkRect* cullRect, const SkPaint& paint);
|
||||
|
||||
/** Draw the text blob, offset by (x,y), using the specified paint.
|
||||
@param blob The text blob to be drawn
|
||||
@param x The x-offset of the text being drawn
|
||||
|
@ -995,6 +1095,9 @@ public:
|
|||
@param paint The paint used for the text (e.g. color, size, style)
|
||||
*/
|
||||
void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint);
|
||||
void drawTextBlob(const sk_sp<SkTextBlob>& blob, SkScalar x, SkScalar y, const SkPaint& paint) {
|
||||
this->drawTextBlob(blob.get(), x, y, paint);
|
||||
}
|
||||
|
||||
/** Draw the picture into this canvas. This method effective brackets the
|
||||
playback of the picture's draw calls with save/restore, so the state
|
||||
|
@ -1026,6 +1129,53 @@ public:
|
|||
this->drawPicture(picture.get(), matrix, paint);
|
||||
}
|
||||
|
||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||
/**
|
||||
* Draw the picture into this canvas, with shadows!
|
||||
*
|
||||
* We will use the canvas's lights along with the picture information (draw depths of
|
||||
* objects, etc) to first create a set of shadowmaps for the light-picture pairs, and
|
||||
* then use that set of shadowmaps to render the scene with shadows.
|
||||
*
|
||||
* If matrix is non-null, apply that matrix to the CTM when drawing this picture. This is
|
||||
* logically equivalent to
|
||||
* save/concat/drawPicture/restore
|
||||
*
|
||||
* If paint is non-null, draw the picture into a temporary buffer, and then apply the paint's
|
||||
* alpha/colorfilter/imagefilter/xfermode to that buffer as it is drawn to the canvas.
|
||||
* This is logically equivalent to
|
||||
* saveLayer(paint)/drawPicture/restore
|
||||
*
|
||||
* We also support using variance shadow maps for blurred shadows; the user can specify
|
||||
* what shadow mapping algorithm to use with params.
|
||||
* - Variance Shadow Mapping works by storing both the depth and depth^2 in the shadow map.
|
||||
* - Then, the shadow map can be blurred, and when reading from it, the fragment shader
|
||||
* can calculate the variance of the depth at a position by doing E(x^2) - E(x)^2.
|
||||
* - We can then use the depth variance and depth at a fragment to arrive at an upper bound
|
||||
* of the probability that the current surface is shadowed by using Chebyshev's
|
||||
* inequality, and then use that to shade the fragment.
|
||||
*
|
||||
* - There are a few problems with VSM.
|
||||
* * Light Bleeding | Areas with high variance, such as near the edges of high up rects,
|
||||
* will cause their shadow penumbras to overwrite otherwise solid
|
||||
* shadows.
|
||||
* * Shape Distortion | We can combat Light Bleeding by biasing the shadow (setting
|
||||
* mostly shaded fragments to completely shaded) and increasing
|
||||
* the minimum allowed variance. However, this warps and rounds
|
||||
* out the shape of the shadow.
|
||||
*/
|
||||
void drawShadowedPicture(const SkPicture*,
|
||||
const SkMatrix* matrix,
|
||||
const SkPaint* paint,
|
||||
const SkShadowParams& params);
|
||||
void drawShadowedPicture(const sk_sp<SkPicture>& picture,
|
||||
const SkMatrix* matrix,
|
||||
const SkPaint* paint,
|
||||
const SkShadowParams& params) {
|
||||
this->drawShadowedPicture(picture.get(), matrix, paint, params);
|
||||
}
|
||||
#endif
|
||||
|
||||
enum VertexMode {
|
||||
kTriangles_VertexMode,
|
||||
kTriangleStrip_VertexMode,
|
||||
|
@ -1220,46 +1370,8 @@ public:
|
|||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** After calling saveLayer(), there can be any number of devices that make
|
||||
up the top-most drawing area. LayerIter can be used to iterate through
|
||||
those devices. Note that the iterator is only valid until the next API
|
||||
call made on the canvas. Ownership of all pointers in the iterator stays
|
||||
with the canvas, so none of them should be modified or deleted.
|
||||
*/
|
||||
class SK_API LayerIter /*: SkNoncopyable*/ {
|
||||
public:
|
||||
/** Initialize iterator with canvas, and set values for 1st device */
|
||||
LayerIter(SkCanvas*, bool skipEmptyClips);
|
||||
~LayerIter();
|
||||
|
||||
/** Return true if the iterator is done */
|
||||
bool done() const { return fDone; }
|
||||
/** Cycle to the next device */
|
||||
void next();
|
||||
|
||||
// These reflect the current device in the iterator
|
||||
|
||||
SkBaseDevice* device() const;
|
||||
const SkMatrix& matrix() const;
|
||||
const SkRegion& clip() const;
|
||||
const SkPaint& paint() const;
|
||||
int x() const;
|
||||
int y() const;
|
||||
|
||||
private:
|
||||
// used to embed the SkDrawIter object directly in our instance, w/o
|
||||
// having to expose that class def to the public. There is an assert
|
||||
// in our constructor to ensure that fStorage is large enough
|
||||
// (though needs to be a compile-time-assert!). We use intptr_t to work
|
||||
// safely with 32 and 64 bit machines (to ensure the storage is enough)
|
||||
intptr_t fStorage[32];
|
||||
class SkDrawIter* fImpl; // this points at fStorage
|
||||
SkPaint fDefaultPaint;
|
||||
bool fDone;
|
||||
};
|
||||
|
||||
// don't call
|
||||
GrRenderTarget* internal_private_accessTopLayerRenderTarget();
|
||||
GrDrawContext* internal_private_accessTopLayerDrawContext();
|
||||
|
||||
// don't call
|
||||
static void Internal_Private_SetIgnoreSaveLayerBounds(bool);
|
||||
|
@ -1275,13 +1387,30 @@ public:
|
|||
const SkPaint* paint,
|
||||
SrcRectConstraint constraint = kStrict_SrcRectConstraint);
|
||||
|
||||
// expose minimum amount of information necessary for transitional refactoring
|
||||
/**
|
||||
* Returns CTM and clip bounds, translated from canvas coordinates to top layer coordinates.
|
||||
*/
|
||||
void temporary_internal_describeTopLayer(SkMatrix* matrix, SkIRect* clip_bounds);
|
||||
|
||||
protected:
|
||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||
/** Returns the current (cumulative) draw depth of the canvas.
|
||||
*/
|
||||
SkScalar getZ() const;
|
||||
|
||||
sk_sp<SkLights> fLights;
|
||||
#endif
|
||||
|
||||
// default impl defers to getDevice()->newSurface(info)
|
||||
virtual sk_sp<SkSurface> onNewSurface(const SkImageInfo&, const SkSurfaceProps&);
|
||||
|
||||
// default impl defers to its device
|
||||
virtual bool onPeekPixels(SkPixmap*);
|
||||
virtual bool onAccessTopLayerPixels(SkPixmap*);
|
||||
virtual SkImageInfo onImageInfo() const;
|
||||
virtual bool onGetProps(SkSurfaceProps*) const;
|
||||
virtual void onFlush();
|
||||
|
||||
// Subclass save/restore notifiers.
|
||||
// Overriders should call the corresponding INHERITED method up the inheritance chain.
|
||||
|
@ -1300,6 +1429,13 @@ protected:
|
|||
virtual void didRestore() {}
|
||||
virtual void didConcat(const SkMatrix&) {}
|
||||
virtual void didSetMatrix(const SkMatrix&) {}
|
||||
virtual void didTranslate(SkScalar dx, SkScalar dy) {
|
||||
this->didConcat(SkMatrix::MakeTrans(dx, dy));
|
||||
}
|
||||
|
||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||
virtual void didTranslateZ(SkScalar) {}
|
||||
#endif
|
||||
|
||||
virtual void onDrawAnnotation(const SkRect&, const char key[], SkData* value);
|
||||
virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&);
|
||||
|
@ -1317,6 +1453,8 @@ protected:
|
|||
virtual void onDrawTextOnPath(const void* text, size_t byteLength,
|
||||
const SkPath& path, const SkMatrix* matrix,
|
||||
const SkPaint& paint);
|
||||
virtual void onDrawTextRSXform(const void* text, size_t byteLength, const SkRSXform[],
|
||||
const SkRect* cullRect, const SkPaint& paint);
|
||||
|
||||
virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
|
||||
const SkPaint& paint);
|
||||
|
@ -1328,7 +1466,10 @@ protected:
|
|||
|
||||
virtual void onDrawPaint(const SkPaint&);
|
||||
virtual void onDrawRect(const SkRect&, const SkPaint&);
|
||||
virtual void onDrawRegion(const SkRegion& region, const SkPaint& paint);
|
||||
virtual void onDrawOval(const SkRect&, const SkPaint&);
|
||||
virtual void onDrawArc(const SkRect&, SkScalar startAngle, SkScalar sweepAngle, bool useCenter,
|
||||
const SkPaint&);
|
||||
virtual void onDrawRRect(const SkRRect&, const SkPaint&);
|
||||
virtual void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&);
|
||||
virtual void onDrawVertices(VertexMode, int vertexCount, const SkPoint vertices[],
|
||||
|
@ -1343,27 +1484,38 @@ protected:
|
|||
SrcRectConstraint);
|
||||
virtual void onDrawImageNine(const SkImage*, const SkIRect& center, const SkRect& dst,
|
||||
const SkPaint*);
|
||||
virtual void onDrawImageLattice(const SkImage*, const Lattice& lattice, const SkRect& dst,
|
||||
const SkPaint*);
|
||||
|
||||
virtual void onDrawBitmap(const SkBitmap&, SkScalar dx, SkScalar dy, const SkPaint*);
|
||||
virtual void onDrawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&, const SkPaint*,
|
||||
SrcRectConstraint);
|
||||
virtual void onDrawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst,
|
||||
const SkPaint*);
|
||||
virtual void onDrawBitmapLattice(const SkBitmap&, const Lattice& lattice, const SkRect& dst,
|
||||
const SkPaint*);
|
||||
|
||||
enum ClipEdgeStyle {
|
||||
kHard_ClipEdgeStyle,
|
||||
kSoft_ClipEdgeStyle
|
||||
};
|
||||
|
||||
virtual void onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle);
|
||||
virtual void onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle);
|
||||
virtual void onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle);
|
||||
virtual void onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op);
|
||||
virtual void onClipRect(const SkRect& rect, ClipOp, ClipEdgeStyle);
|
||||
virtual void onClipRRect(const SkRRect& rrect, ClipOp, ClipEdgeStyle);
|
||||
virtual void onClipPath(const SkPath& path, ClipOp, ClipEdgeStyle);
|
||||
virtual void onClipRegion(const SkRegion& deviceRgn, ClipOp);
|
||||
|
||||
virtual void onDiscard();
|
||||
|
||||
virtual void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*);
|
||||
|
||||
#ifdef SK_EXPERIMENTAL_SHADOWING
|
||||
virtual void onDrawShadowedPicture(const SkPicture*,
|
||||
const SkMatrix*,
|
||||
const SkPaint*,
|
||||
const SkShadowParams& params);
|
||||
#endif
|
||||
|
||||
// Returns the canvas to be used by DrawIter. Default implementation
|
||||
// returns this. Subclasses that encapsulate an indirect canvas may
|
||||
// need to overload this method. The impl must keep track of this, as it
|
||||
|
@ -1378,9 +1530,51 @@ protected:
|
|||
const SkImageFilter* imageFilter = NULL);
|
||||
|
||||
private:
|
||||
/** After calling saveLayer(), there can be any number of devices that make
|
||||
up the top-most drawing area. LayerIter can be used to iterate through
|
||||
those devices. Note that the iterator is only valid until the next API
|
||||
call made on the canvas. Ownership of all pointers in the iterator stays
|
||||
with the canvas, so none of them should be modified or deleted.
|
||||
*/
|
||||
class LayerIter /*: SkNoncopyable*/ {
|
||||
public:
|
||||
/** Initialize iterator with canvas, and set values for 1st device */
|
||||
LayerIter(SkCanvas*);
|
||||
~LayerIter();
|
||||
|
||||
/** Return true if the iterator is done */
|
||||
bool done() const { return fDone; }
|
||||
/** Cycle to the next device */
|
||||
void next();
|
||||
|
||||
// These reflect the current device in the iterator
|
||||
|
||||
SkBaseDevice* device() const;
|
||||
const SkMatrix& matrix() const;
|
||||
const SkRasterClip& clip() const;
|
||||
const SkPaint& paint() const;
|
||||
int x() const;
|
||||
int y() const;
|
||||
|
||||
private:
|
||||
// used to embed the SkDrawIter object directly in our instance, w/o
|
||||
// having to expose that class def to the public. There is an assert
|
||||
// in our constructor to ensure that fStorage is large enough
|
||||
// (though needs to be a compile-time-assert!). We use intptr_t to work
|
||||
// safely with 32 and 64 bit machines (to ensure the storage is enough)
|
||||
intptr_t fStorage[32];
|
||||
class SkDrawIter* fImpl; // this points at fStorage
|
||||
SkPaint fDefaultPaint;
|
||||
bool fDone;
|
||||
};
|
||||
|
||||
static bool BoundsAffectsClip(SaveLayerFlags);
|
||||
static SaveLayerFlags LegacySaveFlagsToSaveLayerFlags(uint32_t legacySaveFlags);
|
||||
|
||||
static void DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filter,
|
||||
SkBaseDevice* dst, const SkMatrix& ctm,
|
||||
const SkClipStack* clipStack);
|
||||
|
||||
enum ShaderOverrideOpacity {
|
||||
kNone_ShaderOverrideOpacity, //!< there is no overriding shader (bitmap or image)
|
||||
kOpaque_ShaderOverrideOpacity, //!< the overriding shader is opaque
|
||||
|
@ -1406,7 +1600,7 @@ private:
|
|||
enum {
|
||||
kMCRecSize = 128, // most recent measurement
|
||||
kMCRecCount = 32, // common depth for save/restores
|
||||
kDeviceCMSize = 136, // most recent measurement
|
||||
kDeviceCMSize = 176, // most recent measurement
|
||||
};
|
||||
intptr_t fMCRecStorage[kMCRecSize * kMCRecCount / sizeof(intptr_t)];
|
||||
intptr_t fDeviceCMStorage[kDeviceCMSize / sizeof(intptr_t)];
|
||||
|
@ -1430,6 +1624,7 @@ private:
|
|||
|
||||
void doSave();
|
||||
void checkForDeferredSave();
|
||||
void internalSetMatrix(const SkMatrix&);
|
||||
|
||||
friend class SkDrawIter; // needs setupDrawForLayerDevice()
|
||||
friend class AutoDrawLooper;
|
||||
|
@ -1437,6 +1632,7 @@ private:
|
|||
friend class SkDebugCanvas; // needs experimental fAllowSimplifyClip
|
||||
friend class SkSurface_Raster; // needs getDevice()
|
||||
friend class SkRecorder; // InitFlags
|
||||
friend class SkLiteRecorder; // InitFlags
|
||||
friend class SkNoSaveLayerCanvas; // InitFlags
|
||||
friend class SkPictureImageFilter; // SkCanvas(SkBaseDevice*, SkSurfaceProps*, InitFlags)
|
||||
friend class SkPictureRecord; // predrawNotify (why does it need it? <reed>)
|
||||
|
@ -1472,7 +1668,7 @@ private:
|
|||
SrcRectConstraint);
|
||||
void internalDrawPaint(const SkPaint& paint);
|
||||
void internalSaveLayer(const SaveLayerRec&, SaveLayerStrategy);
|
||||
void internalDrawDevice(SkBaseDevice*, int x, int y, const SkPaint*, bool isBitmapDevice);
|
||||
void internalDrawDevice(SkBaseDevice*, int x, int y, const SkPaint*);
|
||||
|
||||
// shared by save() and saveLayer()
|
||||
void internalSave();
|
||||
|
@ -1498,25 +1694,18 @@ private:
|
|||
*/
|
||||
bool canDrawBitmapAsSprite(SkScalar x, SkScalar y, int w, int h, const SkPaint&);
|
||||
|
||||
/* These maintain a cache of the clip bounds in local coordinates,
|
||||
(converted to 2s-compliment if floats are slow).
|
||||
|
||||
/**
|
||||
* Keep track of the device clip bounds and if the matrix is scale-translate. This allows
|
||||
* us to do a fast quick reject in the common case.
|
||||
*/
|
||||
mutable SkRect fCachedLocalClipBounds;
|
||||
mutable bool fCachedLocalClipBoundsDirty;
|
||||
bool fIsScaleTranslate;
|
||||
SkRect fDeviceClipBounds;
|
||||
|
||||
bool fAllowSoftClip;
|
||||
bool fAllowSimplifyClip;
|
||||
const bool fConservativeRasterClip;
|
||||
|
||||
const SkRect& getLocalClipBounds() const {
|
||||
if (fCachedLocalClipBoundsDirty) {
|
||||
if (!this->getClipBounds(&fCachedLocalClipBounds)) {
|
||||
fCachedLocalClipBounds.setEmpty();
|
||||
}
|
||||
fCachedLocalClipBoundsDirty = false;
|
||||
}
|
||||
return fCachedLocalClipBounds;
|
||||
}
|
||||
|
||||
class AutoValidateClip : ::SkNoncopyable {
|
||||
public:
|
||||
explicit AutoValidateClip(SkCanvas* canvas) : fCanvas(canvas) {
|
||||
|
@ -1577,9 +1766,9 @@ private:
|
|||
class SkCanvasClipVisitor {
|
||||
public:
|
||||
virtual ~SkCanvasClipVisitor();
|
||||
virtual void clipRect(const SkRect&, SkRegion::Op, bool antialias) = 0;
|
||||
virtual void clipRRect(const SkRRect&, SkRegion::Op, bool antialias) = 0;
|
||||
virtual void clipPath(const SkPath&, SkRegion::Op, bool antialias) = 0;
|
||||
virtual void clipRect(const SkRect&, SkCanvas::ClipOp, bool antialias) = 0;
|
||||
virtual void clipRRect(const SkRRect&, SkCanvas::ClipOp, bool antialias) = 0;
|
||||
virtual void clipPath(const SkPath&, SkCanvas::ClipOp, bool antialias) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -33,7 +33,18 @@ public:
|
|||
kThrow_AllocFailType
|
||||
};
|
||||
|
||||
/**
|
||||
* Allocates a memory block of size bytes.
|
||||
* On success: returns a pointer to beginning of memory block that is
|
||||
* 8 byte aligned. The content of allocated block is not initialized.
|
||||
* On failure: calls abort() if called with kThrow_AllocFailType,
|
||||
* otherwise returns NULL pointer.
|
||||
*/
|
||||
void* alloc(size_t bytes, AllocFailType);
|
||||
|
||||
/**
|
||||
* Shortcut for calling alloc with kThrow_AllocFailType.
|
||||
*/
|
||||
void* allocThrow(size_t bytes) {
|
||||
return this->alloc(bytes, kThrow_AllocFailType);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkClipOp_DEFINED
|
||||
#define SkClipOp_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
// these kept in SkRegion::Op order for now ...
|
||||
enum SkClipOp {
|
||||
kDifference_SkClipOp = 0,
|
||||
kIntersect_SkClipOp = 1,
|
||||
|
||||
// Goal: remove these, since they can grow the current clip
|
||||
|
||||
kUnion_SkClipOp = 2,
|
||||
kXOR_SkClipOp = 3,
|
||||
kReverseDifference_SkClipOp = 4,
|
||||
kReplace_SkClipOp = 5,
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,13 +1,14 @@
|
|||
|
||||
/*
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkClipStack_DEFINED
|
||||
#define SkClipStack_DEFINED
|
||||
|
||||
#include "SkCanvas.h"
|
||||
#include "SkDeque.h"
|
||||
#include "SkPath.h"
|
||||
#include "SkRect.h"
|
||||
|
@ -53,21 +54,21 @@ public:
|
|||
static const int kTypeCnt = kLastType + 1;
|
||||
|
||||
Element() {
|
||||
this->initCommon(0, SkRegion::kReplace_Op, false);
|
||||
this->initCommon(0, SkCanvas::kReplace_Op, false);
|
||||
this->setEmpty();
|
||||
}
|
||||
|
||||
Element(const Element&);
|
||||
|
||||
Element(const SkRect& rect, SkRegion::Op op, bool doAA) {
|
||||
Element(const SkRect& rect, SkCanvas::ClipOp op, bool doAA) {
|
||||
this->initRect(0, rect, op, doAA);
|
||||
}
|
||||
|
||||
Element(const SkRRect& rrect, SkRegion::Op op, bool doAA) {
|
||||
Element(const SkRRect& rrect, SkCanvas::ClipOp op, bool doAA) {
|
||||
this->initRRect(0, rrect, op, doAA);
|
||||
}
|
||||
|
||||
Element(const SkPath& path, SkRegion::Op op, bool doAA) {
|
||||
Element(const SkPath& path, SkCanvas::ClipOp op, bool doAA) {
|
||||
this->initPath(0, path, op, doAA);
|
||||
}
|
||||
|
||||
|
@ -93,7 +94,7 @@ public:
|
|||
}
|
||||
|
||||
//!< Call if getType() is not kEmpty to get the set operation used to combine this element.
|
||||
SkRegion::Op getOp() const { return fOp; }
|
||||
SkCanvas::ClipOp getOp() const { return fOp; }
|
||||
|
||||
//!< Call to get the element as a path, regardless of its type.
|
||||
void asPath(SkPath* path) const;
|
||||
|
@ -109,7 +110,7 @@ public:
|
|||
void invertShapeFillType();
|
||||
|
||||
//!< Sets the set operation represented by the element.
|
||||
void setOp(SkRegion::Op op) { fOp = op; }
|
||||
void setOp(SkCanvas::ClipOp op) { fOp = op; }
|
||||
|
||||
/** The GenID can be used by clip stack clients to cache representations of the clip. The
|
||||
ID corresponds to the set of clip elements up to and including this element within the
|
||||
|
@ -158,6 +159,23 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
bool contains(const SkRRect& rrect) const {
|
||||
switch (fType) {
|
||||
case kRect_Type:
|
||||
return this->getRect().contains(rrect.getBounds());
|
||||
case kRRect_Type:
|
||||
// We don't currently have a generalized rrect-rrect containment.
|
||||
return fRRect.contains(rrect.getBounds()) || rrect == fRRect;
|
||||
case kPath_Type:
|
||||
return fPath.get()->conservativelyContainsRect(rrect.getBounds());
|
||||
case kEmpty_Type:
|
||||
return false;
|
||||
default:
|
||||
SkDEBUGFAIL("Unexpected type.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the clip shape inverse filled.
|
||||
*/
|
||||
|
@ -170,7 +188,7 @@ public:
|
|||
*/
|
||||
void replay(SkCanvasClipVisitor*) const;
|
||||
|
||||
#ifdef SK_DEVELOPER
|
||||
#ifdef SK_DEBUG
|
||||
/**
|
||||
* Dumps the element to SkDebugf. This is intended for Skia development debugging
|
||||
* Don't rely on the existence of this function or the formatting of its output.
|
||||
|
@ -184,7 +202,7 @@ public:
|
|||
SkTLazy<SkPath> fPath;
|
||||
SkRRect fRRect;
|
||||
int fSaveCount; // save count of stack when this element was added.
|
||||
SkRegion::Op fOp;
|
||||
SkCanvas::ClipOp fOp;
|
||||
Type fType;
|
||||
bool fDoAA;
|
||||
|
||||
|
@ -208,23 +226,23 @@ public:
|
|||
int fGenID;
|
||||
|
||||
Element(int saveCount) {
|
||||
this->initCommon(saveCount, SkRegion::kReplace_Op, false);
|
||||
this->initCommon(saveCount, SkCanvas::kReplace_Op, false);
|
||||
this->setEmpty();
|
||||
}
|
||||
|
||||
Element(int saveCount, const SkRRect& rrect, SkRegion::Op op, bool doAA) {
|
||||
Element(int saveCount, const SkRRect& rrect, SkCanvas::ClipOp op, bool doAA) {
|
||||
this->initRRect(saveCount, rrect, op, doAA);
|
||||
}
|
||||
|
||||
Element(int saveCount, const SkRect& rect, SkRegion::Op op, bool doAA) {
|
||||
Element(int saveCount, const SkRect& rect, SkCanvas::ClipOp op, bool doAA) {
|
||||
this->initRect(saveCount, rect, op, doAA);
|
||||
}
|
||||
|
||||
Element(int saveCount, const SkPath& path, SkRegion::Op op, bool doAA) {
|
||||
Element(int saveCount, const SkPath& path, SkCanvas::ClipOp op, bool doAA) {
|
||||
this->initPath(saveCount, path, op, doAA);
|
||||
}
|
||||
|
||||
void initCommon(int saveCount, SkRegion::Op op, bool doAA) {
|
||||
void initCommon(int saveCount, SkCanvas::ClipOp op, bool doAA) {
|
||||
fSaveCount = saveCount;
|
||||
fOp = op;
|
||||
fDoAA = doAA;
|
||||
|
@ -236,13 +254,13 @@ public:
|
|||
fGenID = kInvalidGenID;
|
||||
}
|
||||
|
||||
void initRect(int saveCount, const SkRect& rect, SkRegion::Op op, bool doAA) {
|
||||
void initRect(int saveCount, const SkRect& rect, SkCanvas::ClipOp op, bool doAA) {
|
||||
fRRect.setRect(rect);
|
||||
fType = kRect_Type;
|
||||
this->initCommon(saveCount, op, doAA);
|
||||
}
|
||||
|
||||
void initRRect(int saveCount, const SkRRect& rrect, SkRegion::Op op, bool doAA) {
|
||||
void initRRect(int saveCount, const SkRRect& rrect, SkCanvas::ClipOp op, bool doAA) {
|
||||
SkRRect::Type type = rrect.getType();
|
||||
fRRect = rrect;
|
||||
if (SkRRect::kRect_Type == type || SkRRect::kEmpty_Type == type) {
|
||||
|
@ -253,13 +271,13 @@ public:
|
|||
this->initCommon(saveCount, op, doAA);
|
||||
}
|
||||
|
||||
void initPath(int saveCount, const SkPath& path, SkRegion::Op op, bool doAA);
|
||||
void initPath(int saveCount, const SkPath& path, SkCanvas::ClipOp op, bool doAA);
|
||||
|
||||
void setEmpty();
|
||||
|
||||
// All Element methods below are only used within SkClipStack.cpp
|
||||
inline void checkEmpty() const;
|
||||
inline bool canBeIntersectedInPlace(int saveCount, SkRegion::Op op) const;
|
||||
inline bool canBeIntersectedInPlace(int saveCount, SkCanvas::ClipOp op) const;
|
||||
/* This method checks to see if two rect clips can be safely merged into one. The issue here
|
||||
is that to be strictly correct all the edges of the resulting rect must have the same
|
||||
anti-aliasing. */
|
||||
|
@ -284,8 +302,6 @@ public:
|
|||
|
||||
SkClipStack();
|
||||
SkClipStack(const SkClipStack& b);
|
||||
explicit SkClipStack(const SkRect& r);
|
||||
explicit SkClipStack(const SkIRect& r);
|
||||
~SkClipStack();
|
||||
|
||||
SkClipStack& operator=(const SkClipStack& b);
|
||||
|
@ -312,11 +328,17 @@ public:
|
|||
bool* isIntersectionOfRects = NULL) const;
|
||||
|
||||
/**
|
||||
* Returns true if the input rect in device space is entirely contained
|
||||
* by the clip. A return value of false does not guarantee that the rect
|
||||
* Returns true if the input (r)rect in device space is entirely contained
|
||||
* by the clip. A return value of false does not guarantee that the (r)rect
|
||||
* is not contained by the clip.
|
||||
*/
|
||||
bool quickContains(const SkRect& devRect) const;
|
||||
bool quickContains(const SkRect& devRect) const {
|
||||
return this->isWideOpen() || this->internalQuickContains(devRect);
|
||||
}
|
||||
|
||||
bool quickContains(const SkRRect& devRRect) const {
|
||||
return this->isWideOpen() || this->internalQuickContains(devRRect);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flattens the clip stack into a single SkPath. Returns true if any of
|
||||
|
@ -324,14 +346,14 @@ public:
|
|||
*/
|
||||
bool asPath(SkPath* path) const;
|
||||
|
||||
void clipDevRect(const SkIRect& ir, SkRegion::Op op) {
|
||||
void clipDevRect(const SkIRect& ir, SkCanvas::ClipOp op) {
|
||||
SkRect r;
|
||||
r.set(ir);
|
||||
this->clipDevRect(r, op, false);
|
||||
this->clipRect(r, SkMatrix::I(), op, false);
|
||||
}
|
||||
void clipDevRect(const SkRect&, SkRegion::Op, bool doAA);
|
||||
void clipDevRRect(const SkRRect&, SkRegion::Op, bool doAA);
|
||||
void clipDevPath(const SkPath&, SkRegion::Op, bool doAA);
|
||||
void clipRect(const SkRect&, const SkMatrix& matrix, SkCanvas::ClipOp, bool doAA);
|
||||
void clipRRect(const SkRRect&, const SkMatrix& matrix, SkCanvas::ClipOp, bool doAA);
|
||||
void clipPath(const SkPath&, const SkMatrix& matrix, SkCanvas::ClipOp, bool doAA);
|
||||
// An optimized version of clipDevRect(emptyRect, kIntersect, ...)
|
||||
void clipEmpty();
|
||||
|
||||
|
@ -339,7 +361,22 @@ public:
|
|||
* isWideOpen returns true if the clip state corresponds to the infinite
|
||||
* plane (i.e., draws are not limited at all)
|
||||
*/
|
||||
bool isWideOpen() const;
|
||||
bool isWideOpen() const { return this->getTopmostGenID() == kWideOpenGenID; }
|
||||
|
||||
/**
|
||||
* This method quickly and conservatively determines whether the entire stack is equivalent to
|
||||
* intersection with a rrect given a bounds, where the rrect must not contain the entire bounds.
|
||||
*
|
||||
* @param bounds A bounds on what will be drawn through the clip. The clip only need be
|
||||
* equivalent to a intersection with a rrect for draws within the bounds. The
|
||||
* returned rrect must intersect the bounds but need not be contained by the
|
||||
* bounds.
|
||||
* @param rrect If return is true rrect will contain the rrect equivalent to the stack.
|
||||
* @param aa If return is true aa will indicate whether the equivalent rrect clip is
|
||||
* antialiased.
|
||||
* @return true if the stack is equivalent to a single rrect intersect clip, false otherwise.
|
||||
*/
|
||||
bool isRRect(const SkRect& bounds, SkRRect* rrect, bool* aa) const;
|
||||
|
||||
/**
|
||||
* The generation ID has three reserved values to indicate special
|
||||
|
@ -353,7 +390,7 @@ public:
|
|||
|
||||
int32_t getTopmostGenID() const;
|
||||
|
||||
#ifdef SK_DEVELOPER
|
||||
#ifdef SK_DEBUG
|
||||
/**
|
||||
* Dumps the contents of the clip stack to SkDebugf. This is intended for Skia development
|
||||
* debugging. Don't rely on the existence of this function or the formatting of its output.
|
||||
|
@ -387,7 +424,7 @@ public:
|
|||
* Moves the iterator to the topmost element with the specified RegionOp and returns that
|
||||
* element. If no clip element with that op is found, the first element is returned.
|
||||
*/
|
||||
const Element* skipToTopmost(SkRegion::Op op);
|
||||
const Element* skipToTopmost(SkCanvas::ClipOp op);
|
||||
|
||||
/**
|
||||
* Restarts the iterator on a clip stack.
|
||||
|
@ -461,6 +498,9 @@ private:
|
|||
// invalid ID.
|
||||
static int32_t gGenID;
|
||||
|
||||
bool internalQuickContains(const SkRect& devRect) const;
|
||||
bool internalQuickContains(const SkRRect& devRRect) const;
|
||||
|
||||
/**
|
||||
* Helper for clipDevPath, etc.
|
||||
*/
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#define SkColor_DEFINED
|
||||
|
||||
#include "SkScalar.h"
|
||||
#include "SkPoint3.h"
|
||||
#include "SkTypes.h"
|
||||
|
||||
/** \file SkColor.h
|
||||
|
@ -166,10 +167,10 @@ struct SkPM4f;
|
|||
* The float values are 0...1 unpremultiplied
|
||||
*/
|
||||
struct SkColor4f {
|
||||
float fA;
|
||||
float fR;
|
||||
float fG;
|
||||
float fB;
|
||||
float fA;
|
||||
|
||||
bool operator==(const SkColor4f& other) const {
|
||||
return fA == other.fA && fR == other.fR && fG == other.fG && fB == other.fB;
|
||||
|
@ -178,14 +179,17 @@ struct SkColor4f {
|
|||
return !(*this == other);
|
||||
}
|
||||
|
||||
const float* vec() const { return &fA; }
|
||||
float* vec() { return &fA; }
|
||||
const float* vec() const { return &fR; }
|
||||
float* vec() { return &fR; }
|
||||
|
||||
static SkColor4f Pin(float a, float r, float g, float b);
|
||||
static SkColor4f Pin(float r, float g, float b, float a);
|
||||
static SkColor4f FromColor(SkColor);
|
||||
static SkColor4f FromColor3f(SkColor3f, float a);
|
||||
|
||||
SkColor toSkColor() const;
|
||||
|
||||
SkColor4f pin() const {
|
||||
return Pin(fA, fR, fG, fB);
|
||||
return Pin(fR, fG, fB, fA);
|
||||
}
|
||||
|
||||
SkPM4f premul() const;
|
||||
|
|
|
@ -10,11 +10,13 @@
|
|||
|
||||
#include "SkColor.h"
|
||||
#include "SkFlattenable.h"
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkXfermode.h"
|
||||
|
||||
class GrContext;
|
||||
class GrFragmentProcessor;
|
||||
class SkBitmap;
|
||||
class SkRasterPipeline;
|
||||
|
||||
/**
|
||||
* ColorFilters are optional objects in the drawing pipeline. When present in
|
||||
|
@ -69,6 +71,8 @@ public:
|
|||
|
||||
virtual void filterSpan4f(const SkPM4f src[], int count, SkPM4f result[]) const;
|
||||
|
||||
bool appendStages(SkRasterPipeline*) const;
|
||||
|
||||
enum Flags {
|
||||
/** If set the filter methods will not change the alpha channel of the colors.
|
||||
*/
|
||||
|
@ -111,6 +115,9 @@ public:
|
|||
or NULL if the mode will have no effect.
|
||||
*/
|
||||
static sk_sp<SkColorFilter> MakeModeFilter(SkColor c, SkXfermode::Mode mode);
|
||||
static sk_sp<SkColorFilter> MakeModeFilter(SkColor c, SkBlendMode mode) {
|
||||
return MakeModeFilter(c, (SkXfermode::Mode)mode);
|
||||
}
|
||||
|
||||
/** Construct a colorfilter whose effect is to first apply the inner filter and then apply
|
||||
* the outer filter to the result of the inner's.
|
||||
|
@ -142,6 +149,7 @@ public:
|
|||
}
|
||||
#endif
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
/**
|
||||
* A subclass may implement this factory function to work with the GPU backend. It returns
|
||||
* a GrFragmentProcessor that implemets the color filter in GPU shader code.
|
||||
|
@ -151,9 +159,8 @@ public:
|
|||
*
|
||||
* A null return indicates that the color filter isn't implemented for the GPU backend.
|
||||
*/
|
||||
virtual const GrFragmentProcessor* asFragmentProcessor(GrContext*) const {
|
||||
return nullptr;
|
||||
}
|
||||
virtual sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*) const;
|
||||
#endif
|
||||
|
||||
bool affectsTransparentBlack() const {
|
||||
return this->filterColor(0) != 0;
|
||||
|
@ -167,6 +174,8 @@ public:
|
|||
protected:
|
||||
SkColorFilter() {}
|
||||
|
||||
virtual bool onAppendStages(SkRasterPipeline*) const;
|
||||
|
||||
private:
|
||||
/*
|
||||
* Returns 1 if this is a single filter (not a composition of other filters), otherwise it
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkColorSpace_DEFINED
|
||||
#define SkColorSpace_DEFINED
|
||||
|
||||
#include "SkMatrix44.h"
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
class SkData;
|
||||
|
||||
class SK_API SkColorSpace : public SkRefCnt {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Common, named profiles that we can recognize.
|
||||
*/
|
||||
enum Named : uint8_t {
|
||||
/**
|
||||
* By far the most common color space.
|
||||
* This is the default space for images, unmarked content, and monitors.
|
||||
*/
|
||||
kSRGB_Named,
|
||||
|
||||
/**
|
||||
* Very common wide gamut color space.
|
||||
* Often used by images and monitors.
|
||||
*/
|
||||
kAdobeRGB_Named,
|
||||
|
||||
/**
|
||||
* Colorspace with the sRGB primaries, but a linear (1.0) gamma. Commonly used for
|
||||
* half-float surfaces, and high precision individual colors (gradient stops, etc...)
|
||||
*/
|
||||
kSRGBLinear_Named,
|
||||
};
|
||||
|
||||
enum RenderTargetGamma : uint8_t {
|
||||
kLinear_RenderTargetGamma,
|
||||
|
||||
/**
|
||||
* Transfer function is the canonical sRGB curve, which has a short linear segment
|
||||
* followed by a 2.4f exponential.
|
||||
*/
|
||||
kSRGB_RenderTargetGamma,
|
||||
};
|
||||
|
||||
/**
|
||||
* Create an SkColorSpace from a transfer function and a color gamut transform to D50 XYZ.
|
||||
*/
|
||||
static sk_sp<SkColorSpace> NewRGB(RenderTargetGamma gamma, const SkMatrix44& toXYZD50);
|
||||
|
||||
/**
|
||||
* Create a common, named SkColorSpace.
|
||||
*/
|
||||
static sk_sp<SkColorSpace> NewNamed(Named);
|
||||
|
||||
/**
|
||||
* Create an SkColorSpace from an ICC profile.
|
||||
*/
|
||||
static sk_sp<SkColorSpace> NewICC(const void*, size_t);
|
||||
|
||||
/**
|
||||
* Create an SkColorSpace with the same gamut as this color space, but with linear gamma.
|
||||
*/
|
||||
sk_sp<SkColorSpace> makeLinearGamma();
|
||||
|
||||
/**
|
||||
* Returns true if the color space gamma is near enough to be approximated as sRGB.
|
||||
*/
|
||||
bool gammaCloseToSRGB() const;
|
||||
|
||||
/**
|
||||
* Returns true if the color space gamma is linear.
|
||||
*/
|
||||
bool gammaIsLinear() const;
|
||||
|
||||
/**
|
||||
* Returns nullptr on failure. Fails when we fallback to serializing ICC data and
|
||||
* the data is too large to serialize.
|
||||
*/
|
||||
sk_sp<SkData> serialize() const;
|
||||
|
||||
/**
|
||||
* If |memory| is nullptr, returns the size required to serialize.
|
||||
* Otherwise, serializes into |memory| and returns the size.
|
||||
*/
|
||||
size_t writeToMemory(void* memory) const;
|
||||
|
||||
static sk_sp<SkColorSpace> Deserialize(const void* data, size_t length);
|
||||
|
||||
/**
|
||||
* If both are null, we return true. If one is null and the other is not, we return false.
|
||||
* If both are non-null, we do a deeper compare.
|
||||
*/
|
||||
static bool Equals(const SkColorSpace* src, const SkColorSpace* dst);
|
||||
|
||||
protected:
|
||||
SkColorSpace() {}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -10,7 +10,7 @@
|
|||
#ifndef SkColorTable_DEFINED
|
||||
#define SkColorTable_DEFINED
|
||||
|
||||
#include "../private/SkOncePtr.h"
|
||||
#include "../private/SkOnce.h"
|
||||
#include "SkColor.h"
|
||||
#include "SkFlattenable.h"
|
||||
#include "SkImageInfo.h"
|
||||
|
@ -62,12 +62,14 @@ private:
|
|||
SkColorTable(SkPMColor* colors, int count, AllocatedWithMalloc);
|
||||
|
||||
SkPMColor* fColors;
|
||||
SkOncePtr<uint16_t[]> f16BitCache;
|
||||
mutable uint16_t* f16BitCache = nullptr;
|
||||
mutable SkOnce f16BitCacheOnce;
|
||||
int fCount;
|
||||
|
||||
void init(const SkPMColor* colors, int count);
|
||||
|
||||
friend class SkImageGenerator;
|
||||
friend class SkBitmapRegionCodec;
|
||||
// Only call if no other thread or cache has seen this table.
|
||||
void dangerous_overwriteColors(const SkPMColor newColors[], int count) {
|
||||
if (count < 0 || count > fCount) {
|
||||
|
|
|
@ -14,14 +14,12 @@
|
|||
|
||||
class SkStream;
|
||||
|
||||
#define SK_SUPPORT_LEGACY_DATA_FACTORIES
|
||||
|
||||
/**
|
||||
* SkData holds an immutable data buffer. Not only is the data immutable,
|
||||
* but the actual ptr that is returned (by data() or bytes()) is guaranteed
|
||||
* to always be the same for the life of this instance.
|
||||
*/
|
||||
class SK_API SkData : public SkRefCnt {
|
||||
class SK_API SkData final : public SkNVRefCnt<SkData> {
|
||||
public:
|
||||
/**
|
||||
* Returns the number of bytes stored.
|
||||
|
@ -69,7 +67,6 @@ public:
|
|||
* effectively returning 0 == memcmp(...)
|
||||
*/
|
||||
bool equals(const SkData* other) const;
|
||||
bool equals(sk_sp<const SkData>& other) const { return this->equals(other.get()); }
|
||||
|
||||
/**
|
||||
* Function that, if provided, will be called when the SkData goes out
|
||||
|
@ -82,7 +79,7 @@ public:
|
|||
*/
|
||||
static sk_sp<SkData> MakeWithCopy(const void* data, size_t length);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create a new data with uninitialized contents. The caller should call writable_data()
|
||||
* to write into the buffer, but this must be done before another ref() is made.
|
||||
|
@ -160,38 +157,8 @@ public:
|
|||
*/
|
||||
static sk_sp<SkData> MakeEmpty();
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_DATA_FACTORIES
|
||||
static SkData* NewWithCopy(const void* data, size_t length) {
|
||||
return MakeWithCopy(data, length).release();
|
||||
}
|
||||
static SkData* NewUninitialized(size_t length) {
|
||||
return MakeUninitialized(length).release();
|
||||
}
|
||||
static SkData* NewWithCString(const char cstr[]) {
|
||||
return MakeWithCString(cstr).release();
|
||||
}
|
||||
static SkData* NewWithProc(const void* ptr, size_t length, ReleaseProc proc, void* context) {
|
||||
return MakeWithProc(ptr, length, proc, context).release();
|
||||
}
|
||||
static SkData* NewWithoutCopy(const void* data, size_t length) {
|
||||
return MakeWithoutCopy(data, length).release();
|
||||
}
|
||||
static SkData* NewFromMalloc(const void* data, size_t length) {
|
||||
return MakeFromMalloc(data, length).release();
|
||||
}
|
||||
static SkData* NewFromFileName(const char path[]) { return MakeFromFileName(path).release(); }
|
||||
static SkData* NewFromFILE(FILE* f) { return MakeFromFILE(f).release(); }
|
||||
static SkData* NewFromFD(int fd) { return MakeFromFD(fd).release(); }
|
||||
static SkData* NewFromStream(SkStream* stream, size_t size) {
|
||||
return MakeFromStream(stream, size).release();
|
||||
}
|
||||
static SkData* NewSubset(const SkData* src, size_t offset, size_t length) {
|
||||
return MakeSubset(src, offset, length).release();
|
||||
}
|
||||
static SkData* NewEmpty() { return MakeEmpty().release(); }
|
||||
#endif
|
||||
|
||||
private:
|
||||
friend class SkNVRefCnt<SkData>;
|
||||
ReleaseProc fReleaseProc;
|
||||
void* fReleaseProcContext;
|
||||
void* fPtr;
|
||||
|
@ -199,7 +166,7 @@ private:
|
|||
|
||||
SkData(const void* ptr, size_t size, ReleaseProc, void* context);
|
||||
explicit SkData(size_t size); // inplace new/delete
|
||||
virtual ~SkData();
|
||||
~SkData();
|
||||
|
||||
|
||||
// Objects of this type are sometimes created in a custom fashion using sk_malloc_throw and
|
||||
|
@ -216,14 +183,9 @@ private:
|
|||
// shared internal factory
|
||||
static sk_sp<SkData> PrivateNewWithCopy(const void* srcOrNull, size_t length);
|
||||
|
||||
static void DummyReleaseProc(const void*, void*) {}
|
||||
static void DummyReleaseProc(const void*, void*); // {}
|
||||
|
||||
typedef SkRefCnt INHERITED;
|
||||
};
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_DATA_FACTORIES
|
||||
/** Typedef of SkAutoTUnref<SkData> for automatically unref-ing a SkData. */
|
||||
typedef SkAutoTUnref<SkData> SkAutoDataUnref;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -63,7 +63,7 @@ public:
|
|||
|
||||
typedef void (*FreeProc)(void* context);
|
||||
|
||||
static SkDataTable* NewEmpty();
|
||||
static sk_sp<SkDataTable> MakeEmpty();
|
||||
|
||||
/**
|
||||
* Return a new DataTable that contains a copy of the data stored in each
|
||||
|
@ -74,8 +74,8 @@ public:
|
|||
* ptrs[] array.
|
||||
* @param count the number of array elements in ptrs[] and sizes[] to copy.
|
||||
*/
|
||||
static SkDataTable* NewCopyArrays(const void * const * ptrs,
|
||||
const size_t sizes[], int count);
|
||||
static sk_sp<SkDataTable> MakeCopyArrays(const void * const * ptrs,
|
||||
const size_t sizes[], int count);
|
||||
|
||||
/**
|
||||
* Return a new table that contains a copy of the data in array.
|
||||
|
@ -85,11 +85,10 @@ public:
|
|||
* @param count the number of entries to be copied out of array. The number
|
||||
* of bytes that will be copied is count * elemSize.
|
||||
*/
|
||||
static SkDataTable* NewCopyArray(const void* array, size_t elemSize,
|
||||
int count);
|
||||
static sk_sp<SkDataTable> MakeCopyArray(const void* array, size_t elemSize, int count);
|
||||
|
||||
static SkDataTable* NewArrayProc(const void* array, size_t elemSize,
|
||||
int count, FreeProc proc, void* context);
|
||||
static sk_sp<SkDataTable> MakeArrayProc(const void* array, size_t elemSize, int count,
|
||||
FreeProc proc, void* context);
|
||||
|
||||
private:
|
||||
struct Dir {
|
||||
|
@ -164,7 +163,7 @@ public:
|
|||
* calls to append(). This call also clears any accumluated entries from
|
||||
* this builder, so its count() will be 0 after this call.
|
||||
*/
|
||||
SkDataTable* detachDataTable();
|
||||
sk_sp<SkDataTable> detachDataTable();
|
||||
|
||||
private:
|
||||
SkTDArray<SkDataTable::Dir> fDir;
|
||||
|
|
|
@ -11,17 +11,18 @@
|
|||
#include "SkRefCnt.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkColor.h"
|
||||
#include "SkImageFilter.h"
|
||||
#include "SkSurfaceProps.h"
|
||||
|
||||
class SkBitmap;
|
||||
class SkClipStack;
|
||||
class SkDraw;
|
||||
class SkDrawFilter;
|
||||
class SkImageFilterCache;
|
||||
struct SkIRect;
|
||||
class SkMatrix;
|
||||
class SkMetaData;
|
||||
class SkRegion;
|
||||
class SkSpecialImage;
|
||||
class GrRenderTarget;
|
||||
|
||||
class SK_API SkBaseDevice : public SkRefCnt {
|
||||
|
@ -29,7 +30,7 @@ public:
|
|||
/**
|
||||
* Construct a new device.
|
||||
*/
|
||||
explicit SkBaseDevice(const SkSurfaceProps&);
|
||||
explicit SkBaseDevice(const SkImageInfo&, const SkSurfaceProps&);
|
||||
virtual ~SkBaseDevice();
|
||||
|
||||
SkMetaData& getMetaData();
|
||||
|
@ -38,7 +39,7 @@ public:
|
|||
* Return ImageInfo for this device. If the canvas is not backed by pixels
|
||||
* (cpu or gpu), then the info's ColorType will be kUnknown_SkColorType.
|
||||
*/
|
||||
virtual SkImageInfo imageInfo() const;
|
||||
const SkImageInfo& imageInfo() const { return fInfo; }
|
||||
|
||||
/**
|
||||
* Return SurfaceProps for this device.
|
||||
|
@ -76,6 +77,7 @@ public:
|
|||
return this->imageInfo().isOpaque();
|
||||
}
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_ACCESSBITMAP
|
||||
/** Return the bitmap associated with this device. Call this each time you need
|
||||
to access the bitmap, as it notifies the subclass to perform any flushing
|
||||
etc. before you examine the pixels.
|
||||
|
@ -83,6 +85,7 @@ public:
|
|||
@return the device's bitmap
|
||||
*/
|
||||
const SkBitmap& accessBitmap(bool changePixels);
|
||||
#endif
|
||||
|
||||
bool writePixels(const SkImageInfo&, const void*, size_t rowBytes, int x, int y);
|
||||
|
||||
|
@ -103,44 +106,12 @@ public:
|
|||
*/
|
||||
bool peekPixels(SkPixmap*);
|
||||
|
||||
/**
|
||||
* Return the device's associated gpu render target, or NULL.
|
||||
*/
|
||||
virtual GrRenderTarget* accessRenderTarget() { return NULL; }
|
||||
|
||||
|
||||
/**
|
||||
* Return the device's origin: its offset in device coordinates from
|
||||
* the default origin in its canvas' matrix/clip
|
||||
*/
|
||||
const SkIPoint& getOrigin() const { return fOrigin; }
|
||||
|
||||
/**
|
||||
* onAttachToCanvas is invoked whenever a device is installed in a canvas
|
||||
* (i.e., setDevice, saveLayer (for the new device created by the save),
|
||||
* and SkCanvas' SkBaseDevice & SkBitmap -taking ctors). It allows the
|
||||
* devices to prepare for drawing (e.g., locking their pixels, etc.)
|
||||
*/
|
||||
virtual void onAttachToCanvas(SkCanvas*) {
|
||||
SkASSERT(!fAttachedToCanvas);
|
||||
#ifdef SK_DEBUG
|
||||
fAttachedToCanvas = true;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* onDetachFromCanvas notifies a device that it will no longer be drawn to.
|
||||
* It gives the device a chance to clean up (e.g., unlock its pixels). It
|
||||
* is invoked from setDevice (for the displaced device), restore and
|
||||
* possibly from SkCanvas' dtor.
|
||||
*/
|
||||
virtual void onDetachFromCanvas() {
|
||||
SkASSERT(fAttachedToCanvas);
|
||||
#ifdef SK_DEBUG
|
||||
fAttachedToCanvas = false;
|
||||
#endif
|
||||
};
|
||||
|
||||
protected:
|
||||
enum TileUsage {
|
||||
kPossible_TileUsage, //!< the created device may be drawn tiled
|
||||
|
@ -159,25 +130,6 @@ protected:
|
|||
|
||||
virtual bool onShouldDisableLCD(const SkPaint&) const { return false; }
|
||||
|
||||
/**
|
||||
*
|
||||
* DEPRECATED: This will be removed in a future change. Device subclasses
|
||||
* should use the matrix and clip from the SkDraw passed to draw functions.
|
||||
*
|
||||
* Called with the correct matrix and clip before this device is drawn
|
||||
* to using those settings. If your subclass overrides this, be sure to
|
||||
* call through to the base class as well.
|
||||
*
|
||||
* The clipstack is another view of the clip. It records the actual
|
||||
* geometry that went into building the region. It is present for devices
|
||||
* that want to parse it, but is not required: the region is a complete
|
||||
* picture of the current clip. (i.e. if you regionize all of the geometry
|
||||
* in the clipstack, you will arrive at an equivalent region to the one
|
||||
* passed in).
|
||||
*/
|
||||
virtual void setMatrixClip(const SkMatrix&, const SkRegion&,
|
||||
const SkClipStack&) {};
|
||||
|
||||
/** These are called inside the per-device-layer loop for each draw call.
|
||||
When these are called, we have already applied any saveLayer operations,
|
||||
and are handling any looping from the paint, and any effects from the
|
||||
|
@ -188,8 +140,13 @@ protected:
|
|||
const SkPoint[], const SkPaint& paint) = 0;
|
||||
virtual void drawRect(const SkDraw&, const SkRect& r,
|
||||
const SkPaint& paint) = 0;
|
||||
virtual void drawRegion(const SkDraw&, const SkRegion& r,
|
||||
const SkPaint& paint);
|
||||
virtual void drawOval(const SkDraw&, const SkRect& oval,
|
||||
const SkPaint& paint) = 0;
|
||||
/** By the time this is called we know that abs(sweepAngle) is in the range [0, 360). */
|
||||
virtual void drawArc(const SkDraw&, const SkRect& oval, SkScalar startAngle,
|
||||
SkScalar sweepAngle, bool useCenter, const SkPaint& paint);
|
||||
virtual void drawRRect(const SkDraw&, const SkRRect& rr,
|
||||
const SkPaint& paint) = 0;
|
||||
|
||||
|
@ -226,13 +183,17 @@ protected:
|
|||
const SkPaint& paint,
|
||||
SkCanvas::SrcRectConstraint) = 0;
|
||||
virtual void drawBitmapNine(const SkDraw&, const SkBitmap&, const SkIRect& center,
|
||||
const SkRect& dst, const SkPaint&);
|
||||
const SkRect& dst, const SkPaint&);
|
||||
virtual void drawBitmapLattice(const SkDraw&, const SkBitmap&, const SkCanvas::Lattice&,
|
||||
const SkRect& dst, const SkPaint&);
|
||||
|
||||
virtual void drawImage(const SkDraw&, const SkImage*, SkScalar x, SkScalar y, const SkPaint&);
|
||||
virtual void drawImageRect(const SkDraw&, const SkImage*, const SkRect* src, const SkRect& dst,
|
||||
const SkPaint&, SkCanvas::SrcRectConstraint);
|
||||
virtual void drawImageNine(const SkDraw&, const SkImage*, const SkIRect& center,
|
||||
const SkRect& dst, const SkPaint&);
|
||||
virtual void drawImageLattice(const SkDraw&, const SkImage*, const SkCanvas::Lattice&,
|
||||
const SkRect& dst, const SkPaint&);
|
||||
|
||||
/**
|
||||
* Does not handle text decoration.
|
||||
|
@ -269,38 +230,30 @@ protected:
|
|||
|
||||
virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len, const SkPath&,
|
||||
const SkMatrix*, const SkPaint&);
|
||||
virtual void drawTextRSXform(const SkDraw&, const void* text, size_t len, const SkRSXform[],
|
||||
const SkPaint&);
|
||||
|
||||
virtual void drawSpecial(const SkDraw&, SkSpecialImage*, int x, int y, const SkPaint&);
|
||||
virtual sk_sp<SkSpecialImage> makeSpecial(const SkBitmap&);
|
||||
virtual sk_sp<SkSpecialImage> makeSpecial(const SkImage*);
|
||||
virtual sk_sp<SkSpecialImage> snapSpecial();
|
||||
|
||||
bool readPixels(const SkImageInfo&, void* dst, size_t rowBytes, int x, int y);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_ACCESSBITMAP
|
||||
/** Update as needed the pixel value in the bitmap, so that the caller can
|
||||
access the pixels directly.
|
||||
@return The device contents as a bitmap
|
||||
*/
|
||||
virtual const SkBitmap& onAccessBitmap() = 0;
|
||||
|
||||
/**
|
||||
* Override and return true for filters that the device can handle
|
||||
* intrinsically. Doing so means that SkCanvas will pass-through this
|
||||
* filter to drawSprite and drawDevice (and potentially filterImage).
|
||||
* Returning false means the SkCanvas will have apply the filter itself,
|
||||
* and just pass the resulting image to the device.
|
||||
*/
|
||||
virtual bool canHandleImageFilter(const SkImageFilter*) { return false; }
|
||||
|
||||
/**
|
||||
* Related (but not required) to canHandleImageFilter, this method returns
|
||||
* true if the device could apply the filter to the src bitmap and return
|
||||
* the result (and updates offset as needed).
|
||||
* If the device does not recognize or support this filter,
|
||||
* it just returns false and leaves result and offset unchanged.
|
||||
*/
|
||||
virtual bool filterImage(const SkImageFilter*, const SkBitmap&,
|
||||
const SkImageFilter::Context&,
|
||||
SkBitmap* /*result*/, SkIPoint* /*offset*/) {
|
||||
return false;
|
||||
virtual const SkBitmap& onAccessBitmap() {
|
||||
SkASSERT(0);
|
||||
return fLegacyBitmap;
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual GrContext* context() const { return nullptr; }
|
||||
|
||||
protected:
|
||||
virtual sk_sp<SkSurface> makeSurface(const SkImageInfo&, const SkSurfaceProps&);
|
||||
|
@ -324,19 +277,6 @@ protected:
|
|||
|
||||
virtual bool onAccessPixels(SkPixmap*) { return false; }
|
||||
|
||||
/**
|
||||
* PRIVATE / EXPERIMENTAL -- do not call
|
||||
* This entry point gives the backend an opportunity to take over the rendering
|
||||
* of 'picture'. If optimization data is available (due to an earlier
|
||||
* 'optimize' call) this entry point should make use of it and return true
|
||||
* if all rendering has been done. If false is returned, SkCanvas will
|
||||
* perform its own rendering pass. It is acceptable for the backend
|
||||
* to perform some device-specific warm up tasks and then let SkCanvas
|
||||
* perform the main rendering loop (by return false from here).
|
||||
*/
|
||||
virtual bool EXPERIMENTAL_drawPicture(SkCanvas*, const SkPicture*, const SkMatrix*,
|
||||
const SkPaint*);
|
||||
|
||||
struct CreateInfo {
|
||||
static SkPixelGeometry AdjustGeometry(const SkImageInfo&, TileUsage, SkPixelGeometry,
|
||||
bool preserveLCDText);
|
||||
|
@ -348,22 +288,20 @@ protected:
|
|||
: fInfo(info)
|
||||
, fTileUsage(tileUsage)
|
||||
, fPixelGeometry(AdjustGeometry(info, tileUsage, geo, false))
|
||||
, fForImageFilter(false) {}
|
||||
{}
|
||||
|
||||
CreateInfo(const SkImageInfo& info,
|
||||
TileUsage tileUsage,
|
||||
SkPixelGeometry geo,
|
||||
bool preserveLCDText,
|
||||
bool forImageFilter)
|
||||
bool preserveLCDText)
|
||||
: fInfo(info)
|
||||
, fTileUsage(tileUsage)
|
||||
, fPixelGeometry(AdjustGeometry(info, tileUsage, geo, preserveLCDText))
|
||||
, fForImageFilter(forImageFilter) {}
|
||||
{}
|
||||
|
||||
const SkImageInfo fInfo;
|
||||
const TileUsage fTileUsage;
|
||||
const SkPixelGeometry fPixelGeometry;
|
||||
const bool fForImageFilter;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -381,11 +319,8 @@ protected:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls through to drawSprite, processing the imagefilter.
|
||||
*/
|
||||
virtual void drawSpriteWithFilter(const SkDraw&, const SkBitmap&,
|
||||
int x, int y, const SkPaint&);
|
||||
// A helper function used by derived classes to log the scale factor of a bitmap or image draw.
|
||||
static void LogDrawScaleFactor(const SkMatrix&, SkFilterQuality);
|
||||
|
||||
private:
|
||||
friend class SkCanvas;
|
||||
|
@ -393,9 +328,9 @@ private:
|
|||
friend class SkDraw;
|
||||
friend class SkDrawIter;
|
||||
friend class SkDeviceFilteredPaint;
|
||||
friend class SkImageFilter::DeviceProxy;
|
||||
friend class SkNoPixelsBitmapDevice;
|
||||
friend class SkSurface_Raster;
|
||||
friend class DeviceTestingAccess;
|
||||
|
||||
// used to change the backend's pixels (and possibly config/rowbytes)
|
||||
// but cannot change the width/height, so there should be no change to
|
||||
|
@ -405,6 +340,11 @@ private:
|
|||
|
||||
virtual bool forceConservativeRasterClip() const { return false; }
|
||||
|
||||
/**
|
||||
* Don't call this!
|
||||
*/
|
||||
virtual GrDrawContext* accessDrawContext() { return nullptr; }
|
||||
|
||||
// just called by SkCanvas when built as a layer
|
||||
void setOrigin(int x, int y) { fOrigin.set(x, y); }
|
||||
|
||||
|
@ -412,14 +352,20 @@ private:
|
|||
*/
|
||||
virtual void flush() {}
|
||||
|
||||
virtual SkImageFilter::Cache* getImageFilterCache() { return NULL; }
|
||||
virtual SkImageFilterCache* getImageFilterCache() { return NULL; }
|
||||
|
||||
friend class SkBitmapDevice;
|
||||
void privateResize(int w, int h) {
|
||||
*const_cast<SkImageInfo*>(&fInfo) = fInfo.makeWH(w, h);
|
||||
}
|
||||
|
||||
SkIPoint fOrigin;
|
||||
SkMetaData* fMetaData;
|
||||
SkSurfaceProps fSurfaceProps;
|
||||
const SkImageInfo fInfo;
|
||||
const SkSurfaceProps fSurfaceProps;
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
bool fAttachedToCanvas;
|
||||
#ifdef SK_SUPPORT_LEGACY_ACCESSBITMAP
|
||||
SkBitmap fLegacyBitmap;
|
||||
#endif
|
||||
|
||||
typedef SkRefCnt INHERITED;
|
||||
|
|
|
@ -10,13 +10,13 @@
|
|||
|
||||
#include "SkBitmap.h"
|
||||
#include "SkPicture.h"
|
||||
#include "SkPixelSerializer.h"
|
||||
#include "SkRect.h"
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkString.h"
|
||||
#include "SkTime.h"
|
||||
|
||||
class SkCanvas;
|
||||
class SkPixelSerializer;
|
||||
class SkWStream;
|
||||
|
||||
/** SK_ScalarDefaultDPI is 72 DPI.
|
||||
|
@ -35,12 +35,63 @@ class SkWStream;
|
|||
*/
|
||||
class SK_API SkDocument : public SkRefCnt {
|
||||
public:
|
||||
struct OptionalTimestamp {
|
||||
SkTime::DateTime fDateTime;
|
||||
bool fEnabled;
|
||||
OptionalTimestamp() : fEnabled(false) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a PDF-backed document, writing the results into a SkWStream.
|
||||
* Optional metadata to be passed into the PDF factory function.
|
||||
*/
|
||||
struct PDFMetadata {
|
||||
/**
|
||||
* The document’s title.
|
||||
*/
|
||||
SkString fTitle;
|
||||
/**
|
||||
* The name of the person who created the document.
|
||||
*/
|
||||
SkString fAuthor;
|
||||
/**
|
||||
* The subject of the document.
|
||||
*/
|
||||
SkString fSubject;
|
||||
/**
|
||||
* Keywords associated with the document. Commas may be used
|
||||
* to delineate keywords within the string.
|
||||
*/
|
||||
SkString fKeywords;
|
||||
/**
|
||||
* If the document was converted to PDF from another format,
|
||||
* the name of the conforming product that created the
|
||||
* original document from which it was converted.
|
||||
*/
|
||||
SkString fCreator;
|
||||
/**
|
||||
* The product that is converting this document to PDF.
|
||||
*
|
||||
* Leave fProducer empty to get the default, correct value.
|
||||
*/
|
||||
SkString fProducer;
|
||||
/**
|
||||
* The date and time the document was created.
|
||||
*/
|
||||
OptionalTimestamp fCreation;
|
||||
/**
|
||||
* The date and time the document was most recently modified.
|
||||
*/
|
||||
OptionalTimestamp fModified;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a PDF-backed document, writing the results into a
|
||||
* SkWStream.
|
||||
*
|
||||
* PDF pages are sized in point units. 1 pt == 1/72 inch == 127/360 mm.
|
||||
* PDF pages are sized in point units. 1 pt == 1/72 inch ==
|
||||
* 127/360 mm.
|
||||
*
|
||||
* @param SkWStream* A PDF document will be written to this
|
||||
* @param stream A PDF document will be written to this
|
||||
* stream. The document may write to the stream at
|
||||
* anytime during its lifetime, until either close() is
|
||||
* called or the document is deleted.
|
||||
|
@ -52,49 +103,58 @@ public:
|
|||
* for larger PDF files too, which would use more memory
|
||||
* while rendering, and it would be slower to be processed
|
||||
* or sent online or to printer.
|
||||
* @returns NULL if there is an error, otherwise a newly created
|
||||
* PDF-backed SkDocument.
|
||||
*/
|
||||
static SkDocument* CreatePDF(SkWStream*,
|
||||
SkScalar dpi = SK_ScalarDefaultRasterDPI);
|
||||
|
||||
/**
|
||||
* @param metadata a PDFmetadata object. Any fields may be left
|
||||
* empty.
|
||||
* @param jpegEncoder For PDF documents, if a jpegEncoder is set,
|
||||
* use it to encode SkImages and SkBitmaps as [JFIF]JPEGs.
|
||||
* This feature is deprecated and is only supplied for
|
||||
* backwards compatability.
|
||||
*
|
||||
* The prefered method to create PDFs with JPEG images is
|
||||
* to use SkImage::NewFromEncoded() and not jpegEncoder.
|
||||
* Chromium uses NewFromEncoded.
|
||||
*
|
||||
* If the encoder is unset, or if jpegEncoder->onEncode()
|
||||
* returns NULL, fall back on encoding images losslessly
|
||||
* with Deflate.
|
||||
* @param pdfa Iff true, include XMP metadata, a document UUID,
|
||||
* and sRGB output intent information. This adds length
|
||||
* to the document and makes it non-reproducable, but are
|
||||
* necessary features for PDF/A-2b conformance
|
||||
*
|
||||
* @returns NULL if there is an error, otherwise a newly created
|
||||
* PDF-backed SkDocument.
|
||||
*/
|
||||
static SkDocument* CreatePDF(SkWStream*,
|
||||
SkScalar dpi,
|
||||
SkPixelSerializer* jpegEncoder);
|
||||
static sk_sp<SkDocument> MakePDF(SkWStream* stream,
|
||||
SkScalar dpi,
|
||||
const SkDocument::PDFMetadata& metadata,
|
||||
sk_sp<SkPixelSerializer> jpegEncoder,
|
||||
bool pdfa);
|
||||
|
||||
static sk_sp<SkDocument> MakePDF(SkWStream* stream,
|
||||
SkScalar dpi = SK_ScalarDefaultRasterDPI) {
|
||||
return SkDocument::MakePDF(stream, dpi, SkDocument::PDFMetadata(),
|
||||
nullptr, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a PDF-backed document, writing the results into a file.
|
||||
*/
|
||||
static SkDocument* CreatePDF(const char outputFilePath[],
|
||||
SkScalar dpi = SK_ScalarDefaultRasterDPI);
|
||||
static sk_sp<SkDocument> MakePDF(const char outputFilePath[],
|
||||
SkScalar dpi = SK_ScalarDefaultRasterDPI);
|
||||
|
||||
/**
|
||||
* Create a XPS-backed document, writing the results into the stream.
|
||||
* Returns NULL if XPS is not supported.
|
||||
*/
|
||||
static SkDocument* CreateXPS(SkWStream* stream,
|
||||
SkScalar dpi = SK_ScalarDefaultRasterDPI);
|
||||
static sk_sp<SkDocument> MakeXPS(SkWStream* stream,
|
||||
SkScalar dpi = SK_ScalarDefaultRasterDPI);
|
||||
|
||||
/**
|
||||
* Create a XPS-backed document, writing the results into a file.
|
||||
* Returns NULL if XPS is not supported.
|
||||
*/
|
||||
static SkDocument* CreateXPS(const char path[],
|
||||
SkScalar dpi = SK_ScalarDefaultRasterDPI);
|
||||
static sk_sp<SkDocument> MakeXPS(const char path[],
|
||||
SkScalar dpi = SK_ScalarDefaultRasterDPI);
|
||||
|
||||
/**
|
||||
* Begin a new page for the document, returning the canvas that will draw
|
||||
* into the page. The document owns this canvas, and it will go out of
|
||||
|
@ -115,9 +175,8 @@ public:
|
|||
* or stream holding the document's contents. After close() the document
|
||||
* can no longer add new pages. Deleting the document will automatically
|
||||
* call close() if need be.
|
||||
* Returns true on success or false on failure.
|
||||
*/
|
||||
bool close();
|
||||
void close();
|
||||
|
||||
/**
|
||||
* Call abort() to stop producing the document immediately.
|
||||
|
@ -125,34 +184,6 @@ public:
|
|||
*/
|
||||
void abort();
|
||||
|
||||
/**
|
||||
* Set the document's metadata, if supported by the document
|
||||
* type. The creationDate and modifiedDate parameters can be
|
||||
* nullptr. For example:
|
||||
*
|
||||
* SkDocument* make_doc(SkWStream* output) {
|
||||
* std::vector<SkDocument::Attribute> info;
|
||||
* info.emplace_back(SkString("Title"), SkString("..."));
|
||||
* info.emplace_back(SkString("Author"), SkString("..."));
|
||||
* info.emplace_back(SkString("Subject"), SkString("..."));
|
||||
* info.emplace_back(SkString("Keywords"), SkString("..."));
|
||||
* info.emplace_back(SkString("Creator"), SkString("..."));
|
||||
* SkTime::DateTime now;
|
||||
* SkTime::GetDateTime(&now);
|
||||
* SkDocument* doc = SkDocument::CreatePDF(output);
|
||||
* doc->setMetadata(&info[0], (int)info.size(), &now, &now);
|
||||
* return doc;
|
||||
* }
|
||||
*/
|
||||
struct Attribute {
|
||||
SkString fKey, fValue;
|
||||
Attribute(const SkString& k, const SkString& v) : fKey(k), fValue(v) {}
|
||||
};
|
||||
virtual void setMetadata(const SkDocument::Attribute[],
|
||||
int /* attributeCount */,
|
||||
const SkTime::DateTime* /* creationDate */,
|
||||
const SkTime::DateTime* /* modifiedDate */) {}
|
||||
|
||||
protected:
|
||||
SkDocument(SkWStream*, void (*)(SkWStream*, bool aborted));
|
||||
|
||||
|
@ -163,7 +194,7 @@ protected:
|
|||
virtual SkCanvas* onBeginPage(SkScalar width, SkScalar height,
|
||||
const SkRect& content) = 0;
|
||||
virtual void onEndPage() = 0;
|
||||
virtual bool onClose(SkWStream*) = 0;
|
||||
virtual void onClose(SkWStream*) = 0;
|
||||
virtual void onAbort() = 0;
|
||||
|
||||
// Allows subclasses to write to the stream as pages are written.
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "SkCanvas.h"
|
||||
#include "SkMask.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkStrokeRec.h"
|
||||
|
||||
class SkBitmap;
|
||||
class SkClipStack;
|
||||
|
@ -29,7 +30,6 @@ class SkRRect;
|
|||
class SkDraw {
|
||||
public:
|
||||
SkDraw();
|
||||
SkDraw(const SkDraw& src);
|
||||
|
||||
void drawPaint(const SkPaint&) const;
|
||||
void drawPoints(SkCanvas::PointMode, size_t count, const SkPoint[],
|
||||
|
@ -93,7 +93,7 @@ public:
|
|||
static bool DrawToMask(const SkPath& devPath, const SkIRect* clipBounds,
|
||||
const SkMaskFilter*, const SkMatrix* filterMatrix,
|
||||
SkMask* mask, SkMask::CreateMode mode,
|
||||
SkPaint::Style style);
|
||||
SkStrokeRec::InitStyle style);
|
||||
|
||||
enum RectType {
|
||||
kHair_RectType,
|
||||
|
@ -128,6 +128,9 @@ private:
|
|||
bool pathIsMutable, bool drawCoverage,
|
||||
SkBlitter* customBlitter = NULL) const;
|
||||
|
||||
void drawLine(const SkPoint[2], const SkPaint&) const;
|
||||
void drawDevPath(const SkPath& devPath, const SkPaint& paint, bool drawCoverage,
|
||||
SkBlitter* customBlitter, bool doFill) const;
|
||||
/**
|
||||
* Return the current clip bounds, in local coordinates, with slop to account
|
||||
* for antialiasing or hairlines (i.e. device-bounds outset by 1, and then
|
||||
|
@ -139,17 +142,16 @@ private:
|
|||
bool SK_WARN_UNUSED_RESULT
|
||||
computeConservativeLocalClipBounds(SkRect* bounds) const;
|
||||
|
||||
/** Returns the current setting for using fake gamma. */
|
||||
SkPaint::FakeGamma SK_WARN_UNUSED_RESULT fakeGamma() const;
|
||||
/** Returns the current setting for using fake gamma and contrast. */
|
||||
uint32_t SK_WARN_UNUSED_RESULT scalerContextFlags() const;
|
||||
|
||||
public:
|
||||
SkPixmap fDst;
|
||||
const SkMatrix* fMatrix; // required
|
||||
const SkRegion* fClip; // DEPRECATED
|
||||
const SkRasterClip* fRC; // required
|
||||
|
||||
const SkClipStack* fClipStack; // optional
|
||||
SkBaseDevice* fDevice; // optional
|
||||
const SkClipStack* fClipStack; // optional, may be null
|
||||
SkBaseDevice* fDevice; // optional, may be null
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
void validate() const;
|
||||
|
|
|
@ -8,9 +8,10 @@
|
|||
#ifndef SkDrawable_DEFINED
|
||||
#define SkDrawable_DEFINED
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkFlattenable.h"
|
||||
|
||||
class SkCanvas;
|
||||
class SkMatrix;
|
||||
class SkPicture;
|
||||
struct SkRect;
|
||||
|
||||
|
@ -21,7 +22,7 @@ struct SkRect;
|
|||
* allow for clients of the drawable that may want to cache the results, the drawable must
|
||||
* change its generation ID whenever its internal state changes such that it will draw differently.
|
||||
*/
|
||||
class SkDrawable : public SkRefCnt {
|
||||
class SkDrawable : public SkFlattenable {
|
||||
public:
|
||||
SkDrawable();
|
||||
|
||||
|
@ -58,6 +59,9 @@ public:
|
|||
*/
|
||||
void notifyDrawingChanged();
|
||||
|
||||
SK_DEFINE_FLATTENABLE_TYPE(SkDrawable)
|
||||
Factory getFactory() const override { return nullptr; }
|
||||
|
||||
protected:
|
||||
virtual SkRect onGetBounds() = 0;
|
||||
virtual void onDraw(SkCanvas*) = 0;
|
||||
|
|
|
@ -18,7 +18,9 @@ enum SkFilterQuality {
|
|||
kNone_SkFilterQuality, //!< fastest but lowest quality, typically nearest-neighbor
|
||||
kLow_SkFilterQuality, //!< typically bilerp
|
||||
kMedium_SkFilterQuality, //!< typically bilerp + mipmaps for down-scaling
|
||||
kHigh_SkFilterQuality //!< slowest but highest quality, typically bicubic or better
|
||||
kHigh_SkFilterQuality, //!< slowest but highest quality, typically bicubic or better
|
||||
|
||||
kLast_SkFilterQuality = kHigh_SkFilterQuality
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -71,6 +71,7 @@ class SK_API SkFlattenable : public SkRefCnt {
|
|||
public:
|
||||
enum Type {
|
||||
kSkColorFilter_Type,
|
||||
kSkDrawable_Type,
|
||||
kSkDrawLooper_Type,
|
||||
kSkImageFilter_Type,
|
||||
kSkMaskFilter_Type,
|
||||
|
@ -80,6 +81,7 @@ public:
|
|||
kSkShader_Type,
|
||||
kSkUnused_Type, // used to be SkUnitMapper
|
||||
kSkXfermode_Type,
|
||||
kSkNormalSource_Type,
|
||||
};
|
||||
|
||||
typedef sk_sp<SkFlattenable> (*Factory)(SkReadBuffer&);
|
||||
|
@ -92,9 +94,15 @@ public:
|
|||
*/
|
||||
virtual Factory getFactory() const = 0;
|
||||
|
||||
/** Returns the name of the object's class
|
||||
*/
|
||||
const char* getTypeName() const { return FactoryToName(getFactory()); }
|
||||
/**
|
||||
* Returns the name of the object's class.
|
||||
*
|
||||
* Subclasses should override this function if they intend to provide
|
||||
* support for flattening without using the global registry.
|
||||
*
|
||||
* If the flattenable is registered, there is no need to override.
|
||||
*/
|
||||
virtual const char* getTypeName() const { return FactoryToName(getFactory()); }
|
||||
|
||||
static Factory NameToFactory(const char name[]);
|
||||
static const char* FactoryToName(Factory);
|
||||
|
|
|
@ -117,17 +117,21 @@ public:
|
|||
kLCD_MaskType,
|
||||
};
|
||||
|
||||
static SkFont* Create(SkTypeface*, SkScalar size, MaskType, uint32_t flags);
|
||||
static SkFont* Create(SkTypeface*, SkScalar size, SkScalar scaleX, SkScalar skewX,
|
||||
MaskType, uint32_t flags);
|
||||
static sk_sp<SkFont> Make(sk_sp<SkTypeface>, SkScalar size, MaskType, uint32_t flags);
|
||||
static sk_sp<SkFont> Make(sk_sp<SkTypeface>, SkScalar size, SkScalar scaleX, SkScalar skewX,
|
||||
MaskType, uint32_t flags);
|
||||
|
||||
/**
|
||||
* Return a font with the same attributes of this font, but with the specified size.
|
||||
* If size is not supported (e.g. <= 0 or non-finite) NULL will be returned.
|
||||
*/
|
||||
SkFont* cloneWithSize(SkScalar size) const;
|
||||
sk_sp<SkFont> makeWithSize(SkScalar size) const;
|
||||
/**
|
||||
* Return a font with the same attributes of this font, but with the flags.
|
||||
*/
|
||||
sk_sp<SkFont> makeWithFlags(uint32_t newFlags) const;
|
||||
|
||||
SkTypeface* getTypeface() const { return fTypeface; }
|
||||
SkTypeface* getTypeface() const { return fTypeface.get(); }
|
||||
SkScalar getSize() const { return fSize; }
|
||||
SkScalar getScaleX() const { return fScaleX; }
|
||||
SkScalar getSkewX() const { return fSkewX; }
|
||||
|
@ -139,23 +143,28 @@ public:
|
|||
bool isEnableAutoHints() const { return SkToBool(fFlags & kEnableAutoHints_Flag); }
|
||||
bool isEnableByteCodeHints() const { return SkToBool(fFlags & kEnableByteCodeHints_Flag); }
|
||||
bool isUseNonLinearMetrics() const { return SkToBool(fFlags & kUseNonlinearMetrics_Flag); }
|
||||
bool isDevKern() const { return SkToBool(fFlags & kDevKern_Flag); }
|
||||
|
||||
int textToGlyphs(const void* text, size_t byteLength, SkTextEncoding,
|
||||
uint16_t glyphs[], int maxGlyphCount) const;
|
||||
SkGlyphID glyphs[], int maxGlyphCount) const;
|
||||
|
||||
int countText(const void* text, size_t byteLength, SkTextEncoding encoding) {
|
||||
return this->textToGlyphs(text, byteLength, encoding, nullptr, 0);
|
||||
}
|
||||
|
||||
SkScalar measureText(const void* text, size_t byteLength, SkTextEncoding) const;
|
||||
|
||||
static SkFont* Testing_CreateFromPaint(const SkPaint&);
|
||||
static sk_sp<SkFont> Testing_CreateFromPaint(const SkPaint&);
|
||||
|
||||
private:
|
||||
enum {
|
||||
kAllFlags = 0xFF,
|
||||
};
|
||||
|
||||
SkFont(SkTypeface*, SkScalar size, SkScalar scaleX, SkScalar skewX, MaskType, uint32_t flags);
|
||||
virtual ~SkFont();
|
||||
SkFont(sk_sp<SkTypeface>, SkScalar size, SkScalar scaleX, SkScalar skewX, MaskType,
|
||||
uint32_t flags);
|
||||
|
||||
SkTypeface* fTypeface;
|
||||
sk_sp<SkTypeface> fTypeface;
|
||||
SkScalar fSize;
|
||||
SkScalar fScaleX;
|
||||
SkScalar fSkewX;
|
||||
|
|
|
@ -1,95 +0,0 @@
|
|||
|
||||
/*
|
||||
* Copyright 2006 The Android Open Source Project
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SkFontHost_DEFINED
|
||||
#define SkFontHost_DEFINED
|
||||
|
||||
#include "SkTypeface.h"
|
||||
|
||||
class SkDescriptor;
|
||||
class SkScalerContext;
|
||||
struct SkScalerContextRec;
|
||||
class SkStream;
|
||||
class SkWStream;
|
||||
|
||||
/** \class SkFontHost
|
||||
|
||||
This class is ported to each environment. It is responsible for bridging
|
||||
the gap between the (sort of) abstract class SkTypeface and the
|
||||
platform-specific implementation that provides access to font files.
|
||||
|
||||
One basic task is for each create (subclass of) SkTypeface, the FontHost is
|
||||
responsible for assigning a uniqueID. The ID should be unique for the
|
||||
underlying font file/data, not unique per typeface instance. Thus it is
|
||||
possible/common to request a typeface for the same font more than once
|
||||
(e.g. asking for the same font by name several times). The FontHost may
|
||||
return seperate typeface instances in that case, or it may choose to use a
|
||||
cache and return the same instance (but calling typeface->ref(), since the
|
||||
caller is always responsible for calling unref() on each instance that is
|
||||
returned). Either way, the fontID for those instance(s) will be the same.
|
||||
In addition, the fontID should never be set to 0. That value is used as a
|
||||
sentinel to indicate no-font-id.
|
||||
|
||||
The major aspects are:
|
||||
1) Given either a name/style, return a subclass of SkTypeface that
|
||||
references the closest matching font available on the host system.
|
||||
2) Given the data for a font (either in a stream or a file name), return
|
||||
a typeface that allows access to that data.
|
||||
3) Each typeface instance carries a 32bit ID for its corresponding font.
|
||||
SkFontHost turns that ID into a stream to access the font's data.
|
||||
4) Given a font ID, return a subclass of SkScalerContext, which connects a
|
||||
font scaler (e.g. freetype or other) to the font's data.
|
||||
5) Utilites to manage the font cache (budgeting) and gamma correction
|
||||
*/
|
||||
class SK_API SkFontHost {
|
||||
public:
|
||||
/** LCDs either have their color elements arranged horizontally or
|
||||
vertically. When rendering subpixel glyphs we need to know which way
|
||||
round they are.
|
||||
|
||||
Note, if you change this after startup, you'll need to flush the glyph
|
||||
cache because it'll have the wrong type of masks cached.
|
||||
|
||||
@deprecated use SkPixelGeometry instead.
|
||||
*/
|
||||
enum LCDOrientation {
|
||||
kHorizontal_LCDOrientation = 0, //!< this is the default
|
||||
kVertical_LCDOrientation = 1
|
||||
};
|
||||
|
||||
/** @deprecated set on Device creation. */
|
||||
static void SetSubpixelOrientation(LCDOrientation orientation);
|
||||
/** @deprecated get from Device. */
|
||||
static LCDOrientation GetSubpixelOrientation();
|
||||
|
||||
/** LCD color elements can vary in order. For subpixel text we need to know
|
||||
the order which the LCDs uses so that the color fringes are in the
|
||||
correct place.
|
||||
|
||||
Note, if you change this after startup, you'll need to flush the glyph
|
||||
cache because it'll have the wrong type of masks cached.
|
||||
|
||||
kNONE_LCDOrder means that the subpixel elements are not spatially
|
||||
separated in any usable fashion.
|
||||
|
||||
@deprecated use SkPixelGeometry instead.
|
||||
*/
|
||||
enum LCDOrder {
|
||||
kRGB_LCDOrder = 0, //!< this is the default
|
||||
kBGR_LCDOrder = 1,
|
||||
kNONE_LCDOrder = 2
|
||||
};
|
||||
|
||||
/** @deprecated set on Device creation. */
|
||||
static void SetSubpixelOrder(LCDOrder order);
|
||||
/** @deprecated get from Device. */
|
||||
static LCDOrder GetSubpixelOrder();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
#include "SkTypes.h"
|
||||
|
||||
class SkFontLCDConfig {
|
||||
class SK_API SkFontLCDConfig {
|
||||
public:
|
||||
/** LCDs either have their color elements arranged horizontally or
|
||||
vertically. When rendering subpixel glyphs we need to know which way
|
||||
|
|
|
@ -13,15 +13,17 @@
|
|||
class SK_API SkFontStyle {
|
||||
public:
|
||||
enum Weight {
|
||||
kThin_Weight = 100,
|
||||
kExtraLight_Weight = 200,
|
||||
kLight_Weight = 300,
|
||||
kNormal_Weight = 400,
|
||||
kMedium_Weight = 500,
|
||||
kSemiBold_Weight = 600,
|
||||
kBold_Weight = 700,
|
||||
kExtraBold_Weight = 800,
|
||||
kBlack_Weight = 900
|
||||
kInvisible_Weight = 0,
|
||||
kThin_Weight = 100,
|
||||
kExtraLight_Weight = 200,
|
||||
kLight_Weight = 300,
|
||||
kNormal_Weight = 400,
|
||||
kMedium_Weight = 500,
|
||||
kSemiBold_Weight = 600,
|
||||
kBold_Weight = 700,
|
||||
kExtraBold_Weight = 800,
|
||||
kBlack_Weight = 900,
|
||||
kExtraBlack_Weight = 1000,
|
||||
};
|
||||
|
||||
enum Width {
|
||||
|
@ -33,18 +35,19 @@ public:
|
|||
kSemiExpanded_Width = 6,
|
||||
kExpanded_Width = 7,
|
||||
kExtraExpanded_Width = 8,
|
||||
kUltaExpanded_Width = 9
|
||||
kUltraExpanded_Width = 9,
|
||||
};
|
||||
|
||||
enum Slant {
|
||||
kUpright_Slant,
|
||||
kItalic_Slant,
|
||||
kOblique_Slant,
|
||||
};
|
||||
|
||||
SkFontStyle();
|
||||
SkFontStyle(int weight, int width, Slant);
|
||||
/** oldStyle means the style-bits in SkTypeface::Style: bold=1, italic=2 */
|
||||
explicit SkFontStyle(unsigned oldStyle);
|
||||
|
||||
static SkFontStyle FromOldStyle(unsigned oldStyle);
|
||||
|
||||
bool operator==(const SkFontStyle& rhs) const {
|
||||
return fUnion.fU32 == rhs.fUnion.fU32;
|
||||
|
@ -54,10 +57,6 @@ public:
|
|||
int width() const { return fUnion.fR.fWidth; }
|
||||
Slant slant() const { return (Slant)fUnion.fR.fSlant; }
|
||||
|
||||
bool isItalic() const {
|
||||
return kItalic_Slant == fUnion.fR.fSlant;
|
||||
}
|
||||
|
||||
private:
|
||||
union {
|
||||
struct {
|
||||
|
|
|
@ -28,8 +28,6 @@ class GrContext;
|
|||
class GrContextThreadSafeProxy;
|
||||
class GrTexture;
|
||||
|
||||
#define SK_SUPPORT_LEGACY_IMAGEFACTORY
|
||||
|
||||
/**
|
||||
* SkImage is an abstraction for drawing a rectagle of pixels, though the
|
||||
* particular type of image could be actually storing its data on the GPU, or
|
||||
|
@ -75,7 +73,7 @@ public:
|
|||
*
|
||||
* If a subset is specified, it must be contained within the generator's bounds.
|
||||
*/
|
||||
static sk_sp<SkImage> MakeFromGenerator(SkImageGenerator*, const SkIRect* subset = NULL);
|
||||
static sk_sp<SkImage> MakeFromGenerator(SkImageGenerator*, const SkIRect* subset = nullptr);
|
||||
|
||||
/**
|
||||
* Construct a new SkImage based on the specified encoded data. Returns NULL on failure,
|
||||
|
@ -83,7 +81,7 @@ public:
|
|||
*
|
||||
* If a subset is specified, it must be contained within the encoded data's bounds.
|
||||
*/
|
||||
static sk_sp<SkImage> MakeFromEncoded(sk_sp<SkData> encoded, const SkIRect* subset = NULL);
|
||||
static sk_sp<SkImage> MakeFromEncoded(sk_sp<SkData> encoded, const SkIRect* subset = nullptr);
|
||||
|
||||
/**
|
||||
* Create a new image from the specified descriptor. Note - the caller is responsible for
|
||||
|
@ -92,12 +90,12 @@ public:
|
|||
* Will return NULL if the specified descriptor is unsupported.
|
||||
*/
|
||||
static sk_sp<SkImage> MakeFromTexture(GrContext* ctx, const GrBackendTextureDesc& desc) {
|
||||
return MakeFromTexture(ctx, desc, kPremul_SkAlphaType, NULL, NULL);
|
||||
return MakeFromTexture(ctx, desc, kPremul_SkAlphaType, nullptr, nullptr, nullptr);
|
||||
}
|
||||
|
||||
static sk_sp<SkImage> MakeFromTexture(GrContext* ctx, const GrBackendTextureDesc& de,
|
||||
SkAlphaType at) {
|
||||
return MakeFromTexture(ctx, de, at, NULL, NULL);
|
||||
return MakeFromTexture(ctx, de, at, nullptr, nullptr, nullptr);
|
||||
}
|
||||
|
||||
typedef void (*TextureReleaseProc)(ReleaseContext);
|
||||
|
@ -109,8 +107,21 @@ public:
|
|||
*
|
||||
* Will return NULL if the specified descriptor is unsupported.
|
||||
*/
|
||||
static sk_sp<SkImage> MakeFromTexture(GrContext* ctx, const GrBackendTextureDesc& desc,
|
||||
SkAlphaType at, TextureReleaseProc trp,
|
||||
ReleaseContext rc) {
|
||||
return MakeFromTexture(ctx, desc, at, nullptr, trp, rc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new image from the specified descriptor. The underlying platform texture must stay
|
||||
* valid and unaltered until the specified release-proc is invoked, indicating that Skia
|
||||
* no longer is holding a reference to it.
|
||||
*
|
||||
* Will return NULL if the specified descriptor is unsupported.
|
||||
*/
|
||||
static sk_sp<SkImage> MakeFromTexture(GrContext*, const GrBackendTextureDesc&, SkAlphaType,
|
||||
TextureReleaseProc, ReleaseContext);
|
||||
sk_sp<SkColorSpace>, TextureReleaseProc, ReleaseContext);
|
||||
|
||||
/**
|
||||
* Create a new image from the specified descriptor. Note - Skia will delete or recycle the
|
||||
|
@ -119,16 +130,8 @@ public:
|
|||
* Will return NULL if the specified descriptor is unsupported.
|
||||
*/
|
||||
static sk_sp<SkImage> MakeFromAdoptedTexture(GrContext*, const GrBackendTextureDesc&,
|
||||
SkAlphaType = kPremul_SkAlphaType);
|
||||
|
||||
/**
|
||||
* Create a new image by copying the pixels from the specified descriptor. No reference is
|
||||
* kept to the original platform texture.
|
||||
*
|
||||
* Will return NULL if the specified descriptor is unsupported.
|
||||
*/
|
||||
static sk_sp<SkImage> MakeFromTextureCopy(GrContext*, const GrBackendTextureDesc&,
|
||||
SkAlphaType = kPremul_SkAlphaType);
|
||||
SkAlphaType = kPremul_SkAlphaType,
|
||||
sk_sp<SkColorSpace> = nullptr);
|
||||
|
||||
/**
|
||||
* Create a new image by copying the pixels from the specified y, u, v textures. The data
|
||||
|
@ -138,7 +141,18 @@ public:
|
|||
static sk_sp<SkImage> MakeFromYUVTexturesCopy(GrContext*, SkYUVColorSpace,
|
||||
const GrBackendObject yuvTextureHandles[3],
|
||||
const SkISize yuvSizes[3],
|
||||
GrSurfaceOrigin);
|
||||
GrSurfaceOrigin,
|
||||
sk_sp<SkColorSpace> = nullptr);
|
||||
|
||||
/**
|
||||
* Create a new image by copying the pixels from the specified y and uv textures. The data
|
||||
* from the textures is immediately ingested into the image and the textures can be modified or
|
||||
* deleted after the function returns. The image will have the dimensions of the y texture.
|
||||
*/
|
||||
static sk_sp<SkImage> MakeFromNV12TexturesCopy(GrContext*, SkYUVColorSpace,
|
||||
const GrBackendObject nv12TextureHandles[2],
|
||||
const SkISize nv12Sizes[2], GrSurfaceOrigin,
|
||||
sk_sp<SkColorSpace> = nullptr);
|
||||
|
||||
static sk_sp<SkImage> MakeFromPicture(sk_sp<SkPicture>, const SkISize& dimensions,
|
||||
const SkMatrix*, const SkPaint*);
|
||||
|
@ -152,7 +166,8 @@ public:
|
|||
SkISize dimensions() const { return SkISize::Make(fWidth, fHeight); }
|
||||
SkIRect bounds() const { return SkIRect::MakeWH(fWidth, fHeight); }
|
||||
uint32_t uniqueID() const { return fUniqueID; }
|
||||
virtual bool isOpaque() const { return false; }
|
||||
SkAlphaType alphaType() const;
|
||||
bool isOpaque() const { return SkAlphaTypeIsOpaque(this->alphaType()); }
|
||||
|
||||
/**
|
||||
* Extracts YUV planes from the SkImage and stores them in client-provided memory. The sizes
|
||||
|
@ -322,10 +337,40 @@ public:
|
|||
*/
|
||||
sk_sp<SkImage> makeTextureImage(GrContext*) const;
|
||||
|
||||
/**
|
||||
* If the image is texture-backed this will make a raster copy of it (or nullptr if reading back
|
||||
* the pixels fails). Otherwise, it returns the original image.
|
||||
*/
|
||||
sk_sp<SkImage> makeNonTextureImage() const;
|
||||
/**
|
||||
* Apply a given image filter to this image, and return the filtered result.
|
||||
*
|
||||
* The subset represents the active portion of this image. The return value is similarly an
|
||||
* SkImage, with an active subset (outSubset). This is usually used with texture-backed
|
||||
* images, where the texture may be approx-match and thus larger than the required size.
|
||||
*
|
||||
* clipBounds constrains the device-space extent of the image which may be produced to the
|
||||
* given rect.
|
||||
*
|
||||
* offset is the amount to translate the resulting image relative to the src when it is drawn.
|
||||
* This is an out-param.
|
||||
*
|
||||
* If the result image cannot be created, or the result would be transparent black, null
|
||||
* is returned, in which case the offset and outSubset parameters should be ignored by the
|
||||
* caller.
|
||||
*/
|
||||
sk_sp<SkImage> makeWithFilter(const SkImageFilter* filter, const SkIRect& subset,
|
||||
const SkIRect& clipBounds, SkIRect* outSubset,
|
||||
SkIPoint* offset) const;
|
||||
|
||||
/** Drawing params for which a deferred texture image data should be optimized. */
|
||||
struct DeferredTextureImageUsageParams {
|
||||
DeferredTextureImageUsageParams(const SkMatrix matrix, const SkFilterQuality quality,
|
||||
int preScaleMipLevel)
|
||||
: fMatrix(matrix), fQuality(quality), fPreScaleMipLevel(preScaleMipLevel) {}
|
||||
SkMatrix fMatrix;
|
||||
SkFilterQuality fQuality;
|
||||
int fPreScaleMipLevel;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -351,7 +396,9 @@ public:
|
|||
size_t getDeferredTextureImageData(const GrContextThreadSafeProxy&,
|
||||
const DeferredTextureImageUsageParams[],
|
||||
int paramCnt,
|
||||
void* buffer) const;
|
||||
void* buffer,
|
||||
SkSourceGammaTreatment treatment =
|
||||
SkSourceGammaTreatment::kIgnore) const;
|
||||
|
||||
/**
|
||||
* Returns a texture-backed image from data produced in SkImage::getDeferredTextureImageData.
|
||||
|
@ -377,7 +424,7 @@ public:
|
|||
* to empty.
|
||||
*/
|
||||
bool asLegacyBitmap(SkBitmap*, LegacyBitmapMode) const;
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the image is backed by an image-generator or other src that creates
|
||||
* (and caches) its pixels / texture on-demand.
|
||||
|
@ -392,21 +439,19 @@ public:
|
|||
static SkImage* NewFromRaster(const Info&, const void* pixels, size_t rowBytes,
|
||||
RasterReleaseProc, ReleaseContext);
|
||||
static SkImage* NewFromBitmap(const SkBitmap&);
|
||||
static SkImage* NewFromGenerator(SkImageGenerator*, const SkIRect* subset = NULL);
|
||||
static SkImage* NewFromEncoded(SkData* encoded, const SkIRect* subset = NULL);
|
||||
static SkImage* NewFromGenerator(SkImageGenerator*, const SkIRect* subset = nullptr);
|
||||
static SkImage* NewFromEncoded(SkData* encoded, const SkIRect* subset = nullptr);
|
||||
static SkImage* NewFromTexture(GrContext* ctx, const GrBackendTextureDesc& desc) {
|
||||
return NewFromTexture(ctx, desc, kPremul_SkAlphaType, NULL, NULL);
|
||||
return NewFromTexture(ctx, desc, kPremul_SkAlphaType, nullptr, nullptr);
|
||||
}
|
||||
|
||||
static SkImage* NewFromTexture(GrContext* ctx, const GrBackendTextureDesc& de, SkAlphaType at) {
|
||||
return NewFromTexture(ctx, de, at, NULL, NULL);
|
||||
return NewFromTexture(ctx, de, at, nullptr, nullptr);
|
||||
}
|
||||
static SkImage* NewFromTexture(GrContext*, const GrBackendTextureDesc&, SkAlphaType,
|
||||
TextureReleaseProc, ReleaseContext);
|
||||
static SkImage* NewFromAdoptedTexture(GrContext*, const GrBackendTextureDesc&,
|
||||
SkAlphaType = kPremul_SkAlphaType);
|
||||
static SkImage* NewFromTextureCopy(GrContext*, const GrBackendTextureDesc&,
|
||||
SkAlphaType = kPremul_SkAlphaType);
|
||||
static SkImage* NewFromYUVTexturesCopy(GrContext*, SkYUVColorSpace,
|
||||
const GrBackendObject yuvTextureHandles[3],
|
||||
const SkISize yuvSizes[3],
|
||||
|
@ -424,6 +469,10 @@ protected:
|
|||
SkImage(int width, int height, uint32_t uniqueID);
|
||||
|
||||
private:
|
||||
static sk_sp<SkImage> MakeTextureFromMipMap(GrContext*, const SkImageInfo&,
|
||||
const GrMipLevel* texels, int mipLevelCount,
|
||||
SkBudgeted, SkSourceGammaTreatment);
|
||||
|
||||
const int fWidth;
|
||||
const int fHeight;
|
||||
const uint32_t fUniqueID;
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkImageDeserializer_DEFINED
|
||||
#define SkImageDeserializer_DEFINED
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
struct SkIRect;
|
||||
class SkData;
|
||||
class SkImage;
|
||||
|
||||
class SK_API SkImageDeserializer {
|
||||
public:
|
||||
virtual ~SkImageDeserializer() {}
|
||||
|
||||
/**
|
||||
* Given a data containing serialized content, return an SkImage from it.
|
||||
*
|
||||
* @param data The data containing the encoded image. The subclass may ref this for later
|
||||
* decoding, or read it and process it immediately.
|
||||
* @param subset Optional rectangle represent the subset of the encoded data that is being
|
||||
* requested to be turned into an image.
|
||||
* @return The new image, or nullptr on failure.
|
||||
*
|
||||
* The default implementation is to call SkImage::MakeFromEncoded(...)
|
||||
*/
|
||||
virtual sk_sp<SkImage> makeFromData(SkData*, const SkIRect* subset);
|
||||
virtual sk_sp<SkImage> makeFromMemory(const void* data, size_t length, const SkIRect* subset);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -91,7 +91,7 @@ protected:
|
|||
// This macro declares a global (i.e., non-class owned) creation entry point
|
||||
// for each encoder (e.g., CreateJPEGImageEncoder)
|
||||
#define DECLARE_ENCODER_CREATOR(codec) \
|
||||
SkImageEncoder *Create ## codec ();
|
||||
SK_API SkImageEncoder *Create ## codec ();
|
||||
|
||||
// This macro defines the global creation entry point for each encoder. Each
|
||||
// encoder implementation that registers with the encoder factory must call it.
|
||||
|
@ -100,22 +100,17 @@ protected:
|
|||
|
||||
// All the encoders known by Skia. Note that, depending on the compiler settings,
|
||||
// not all of these will be available
|
||||
/** An ARGBImageEncoder will always write out
|
||||
* bitmap.width() * bitmap.height() * 4
|
||||
* bytes.
|
||||
*/
|
||||
DECLARE_ENCODER_CREATOR(ARGBImageEncoder);
|
||||
DECLARE_ENCODER_CREATOR(JPEGImageEncoder);
|
||||
DECLARE_ENCODER_CREATOR(PNGImageEncoder);
|
||||
DECLARE_ENCODER_CREATOR(KTXImageEncoder);
|
||||
DECLARE_ENCODER_CREATOR(WEBPImageEncoder);
|
||||
|
||||
#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
|
||||
DECLARE_ENCODER_CREATOR(PNGImageEncoder_CG);
|
||||
SkImageEncoder* CreateImageEncoder_CG(SkImageEncoder::Type type);
|
||||
#endif
|
||||
|
||||
#if defined(SK_BUILD_FOR_WIN)
|
||||
DECLARE_ENCODER_CREATOR(ImageEncoder_WIC);
|
||||
SkImageEncoder* CreateImageEncoder_WIC(SkImageEncoder::Type type);
|
||||
#endif
|
||||
|
||||
// Typedef to make registering encoder callback easier
|
||||
|
|
|
@ -11,19 +11,19 @@
|
|||
#include "../private/SkTArray.h"
|
||||
#include "../private/SkTemplates.h"
|
||||
#include "../private/SkMutex.h"
|
||||
#include "SkColorSpace.h"
|
||||
#include "SkFilterQuality.h"
|
||||
#include "SkFlattenable.h"
|
||||
#include "SkMatrix.h"
|
||||
#include "SkRect.h"
|
||||
#include "SkSurfaceProps.h"
|
||||
|
||||
class GrContext;
|
||||
class GrFragmentProcessor;
|
||||
class GrTexture;
|
||||
class SkBaseDevice;
|
||||
class SkBitmap;
|
||||
class SkColorFilter;
|
||||
struct SkIPoint;
|
||||
class SkSpecialImage;
|
||||
class SkImageFilterCache;
|
||||
struct SkImageFilterCacheKey;
|
||||
|
||||
/**
|
||||
* Base class for image filters. If one is installed in the paint, then
|
||||
|
@ -34,38 +34,42 @@ class SkSpecialImage;
|
|||
*/
|
||||
class SK_API SkImageFilter : public SkFlattenable {
|
||||
public:
|
||||
// This cache maps from (filter's unique ID + CTM + clipBounds + src bitmap generation ID) to
|
||||
// (result, offset).
|
||||
class Cache : public SkRefCnt {
|
||||
// Extra information about the output of a filter DAG. For now, this is just the color space
|
||||
// (of the original requesting device). This is used when constructing intermediate rendering
|
||||
// surfaces, so that we ensure we land in a surface that's similar/compatible to the final
|
||||
// consumer of the DAG's output.
|
||||
class OutputProperties {
|
||||
public:
|
||||
struct Key;
|
||||
virtual ~Cache() {}
|
||||
static Cache* Create(size_t maxBytes);
|
||||
static Cache* Get();
|
||||
virtual bool get(const Key& key, SkBitmap* result, SkIPoint* offset) const = 0;
|
||||
virtual SkSpecialImage* get(const Key& key, SkIPoint* offset) const = 0;
|
||||
virtual void set(const Key& key, const SkBitmap& result, const SkIPoint& offset) = 0;
|
||||
virtual void set(const Key& key, SkSpecialImage* image, const SkIPoint& offset) = 0;
|
||||
virtual void purge() {}
|
||||
virtual void purgeByKeys(const Key[], int) {}
|
||||
explicit OutputProperties(SkColorSpace* colorSpace) : fColorSpace(colorSpace) {}
|
||||
|
||||
SkColorSpace* colorSpace() const { return fColorSpace; }
|
||||
|
||||
private:
|
||||
// This will be a pointer to the device's color space, and our lifetime is bounded by
|
||||
// the device, so we can store a bare pointer.
|
||||
SkColorSpace* fColorSpace;
|
||||
};
|
||||
|
||||
class Context {
|
||||
public:
|
||||
Context(const SkMatrix& ctm, const SkIRect& clipBounds, Cache* cache)
|
||||
Context(const SkMatrix& ctm, const SkIRect& clipBounds, SkImageFilterCache* cache,
|
||||
const OutputProperties& outputProperties)
|
||||
: fCTM(ctm)
|
||||
, fClipBounds(clipBounds)
|
||||
, fCache(cache)
|
||||
, fOutputProperties(outputProperties)
|
||||
{}
|
||||
|
||||
const SkMatrix& ctm() const { return fCTM; }
|
||||
const SkIRect& clipBounds() const { return fClipBounds; }
|
||||
Cache* cache() const { return fCache; }
|
||||
SkImageFilterCache* cache() const { return fCache; }
|
||||
const OutputProperties& outputProperties() const { return fOutputProperties; }
|
||||
|
||||
private:
|
||||
SkMatrix fCTM;
|
||||
SkIRect fClipBounds;
|
||||
Cache* fCache;
|
||||
SkMatrix fCTM;
|
||||
SkIRect fClipBounds;
|
||||
SkImageFilterCache* fCache;
|
||||
OutputProperties fOutputProperties;
|
||||
};
|
||||
|
||||
class CropRect {
|
||||
|
@ -109,38 +113,8 @@ public:
|
|||
kNever_TileUsage, //!< the created device will never be drawn tiled
|
||||
};
|
||||
|
||||
class Proxy {
|
||||
public:
|
||||
virtual ~Proxy() {}
|
||||
|
||||
virtual SkBaseDevice* createDevice(int width, int height,
|
||||
TileUsage usage = kNever_TileUsage) = 0;
|
||||
|
||||
// Returns true if the proxy handled the filter itself. If this returns
|
||||
// false then the filter's code will be called.
|
||||
virtual bool filterImage(const SkImageFilter*, const SkBitmap& src,
|
||||
const SkImageFilter::Context&,
|
||||
SkBitmap* result, SkIPoint* offset) = 0;
|
||||
};
|
||||
|
||||
class DeviceProxy : public Proxy {
|
||||
public:
|
||||
DeviceProxy(SkBaseDevice* device) : fDevice(device) {}
|
||||
|
||||
SkBaseDevice* createDevice(int width, int height,
|
||||
TileUsage usage = kNever_TileUsage) override;
|
||||
|
||||
// Returns true if the proxy handled the filter itself. If this returns
|
||||
// false then the filter's code will be called.
|
||||
bool filterImage(const SkImageFilter*, const SkBitmap& src, const SkImageFilter::Context&,
|
||||
SkBitmap* result, SkIPoint* offset) override;
|
||||
|
||||
private:
|
||||
SkBaseDevice* fDevice;
|
||||
};
|
||||
|
||||
/**
|
||||
* Request a new (result) image to be created from the src image.
|
||||
* Request a new filtered image to be created from the src image.
|
||||
*
|
||||
* The context contains the environment in which the filter is occurring.
|
||||
* It includes the clip bounds, CTM and cache.
|
||||
|
@ -148,8 +122,9 @@ public:
|
|||
* Offset is the amount to translate the resulting image relative to the
|
||||
* src when it is drawn. This is an out-param.
|
||||
*
|
||||
* If the result image cannot be created, return null, in which case
|
||||
* the offset parameters will be ignored by the caller.
|
||||
* If the result image cannot be created, or the result would be
|
||||
* transparent black, return null, in which case the offset parameter
|
||||
* should be ignored by the caller.
|
||||
*
|
||||
* TODO: Right now the imagefilters sometimes return empty result bitmaps/
|
||||
* specialimages. That doesn't seem quite right.
|
||||
|
@ -174,27 +149,12 @@ public:
|
|||
SkIRect filterBounds(const SkIRect& src, const SkMatrix& ctm,
|
||||
MapDirection = kReverse_MapDirection) const;
|
||||
|
||||
/**
|
||||
* Returns true if the filter can be processed on the GPU. This is most
|
||||
* often used for multi-pass effects, where intermediate results must be
|
||||
* rendered to textures. For single-pass effects, use asFragmentProcessor().
|
||||
* The default implementation returns asFragmentProcessor(NULL, NULL, SkMatrix::I(),
|
||||
* SkIRect()).
|
||||
*/
|
||||
virtual bool canFilterImageGPU() const;
|
||||
|
||||
/**
|
||||
* Process this image filter on the GPU. This is most often used for
|
||||
* multi-pass effects, where intermediate results must be rendered to
|
||||
* textures. For single-pass effects, use asFragmentProcessor(). src is the
|
||||
* source image for processing, as a texture-backed bitmap. result is
|
||||
* the destination bitmap, which should contain a texture-backed pixelref
|
||||
* on success. offset is the amount to translate the resulting image
|
||||
* relative to the src when it is drawn. The default implementation does
|
||||
* single-pass processing using asFragmentProcessor().
|
||||
*/
|
||||
virtual bool filterImageGPUDeprecated(Proxy*, const SkBitmap& src, const Context&,
|
||||
SkBitmap* result, SkIPoint* offset) const;
|
||||
#if SK_SUPPORT_GPU
|
||||
static sk_sp<SkSpecialImage> DrawWithFP(GrContext* context,
|
||||
sk_sp<GrFragmentProcessor> fp,
|
||||
const SkIRect& bounds,
|
||||
const OutputProperties& outputProperties);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Returns whether this image filter is a color filter and puts the color filter into the
|
||||
|
@ -212,6 +172,10 @@ public:
|
|||
return this->isColorFilterNode(filterPtr);
|
||||
}
|
||||
|
||||
static sk_sp<SkImageFilter> MakeBlur(SkScalar sigmaX, SkScalar sigmaY,
|
||||
sk_sp<SkImageFilter> input,
|
||||
const CropRect* cropRect = nullptr);
|
||||
|
||||
/**
|
||||
* Returns true (and optionally returns a ref'd filter) if this imagefilter can be completely
|
||||
* replaced by the returned colorfilter. i.e. the two effects will affect drawing in the
|
||||
|
@ -223,15 +187,15 @@ public:
|
|||
* Returns the number of inputs this filter will accept (some inputs can
|
||||
* be NULL).
|
||||
*/
|
||||
int countInputs() const { return fInputCount; }
|
||||
int countInputs() const { return fInputs.count(); }
|
||||
|
||||
/**
|
||||
* Returns the input filter at a given index, or NULL if no input is
|
||||
* connected. The indices used are filter-specific.
|
||||
*/
|
||||
SkImageFilter* getInput(int i) const {
|
||||
SkASSERT(i < fInputCount);
|
||||
return fInputs[i];
|
||||
SkASSERT(i < fInputs.count());
|
||||
return fInputs[i].get();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -241,9 +205,7 @@ public:
|
|||
* The size of the crop rect should be
|
||||
* used as the size of the destination image. The origin of this rect
|
||||
* should be used to offset access to the input images, and should also
|
||||
* be added to the "offset" parameter in onFilterImage and
|
||||
* filterImageGPU(). (The latter ensures that the resulting buffer is
|
||||
* drawn in the correct location.)
|
||||
* be added to the "offset" parameter in onFilterImage.
|
||||
*/
|
||||
bool cropRectIsSet() const { return fCropRect.flags() != 0x0; }
|
||||
|
||||
|
@ -268,11 +230,19 @@ public:
|
|||
#endif
|
||||
|
||||
/**
|
||||
* Create an SkMatrixImageFilter, which transforms its input by the given matrix.
|
||||
* ImageFilters can natively handle scaling and translate components in the CTM. Only some of
|
||||
* them can handle affine (or more complex) matrices. This call returns true iff the filter
|
||||
* and all of its (non-null) inputs can handle these more complex matrices.
|
||||
*/
|
||||
bool canHandleComplexCTM() const;
|
||||
|
||||
/**
|
||||
* Return an imagefilter which transforms its input by the given matrix.
|
||||
*/
|
||||
static sk_sp<SkImageFilter> MakeMatrixFilter(const SkMatrix& matrix,
|
||||
SkFilterQuality,
|
||||
SkFilterQuality quality,
|
||||
sk_sp<SkImageFilter> input);
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_IMAGEFILTER_PTR
|
||||
static SkImageFilter* CreateMatrixFilter(const SkMatrix& matrix,
|
||||
SkFilterQuality filterQuality,
|
||||
|
@ -281,26 +251,9 @@ public:
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
sk_sp<SkSpecialImage> filterInput(int index,
|
||||
SkSpecialImage* src,
|
||||
const Context&,
|
||||
SkIPoint* offset) const;
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
// Helper function which invokes GPU filter processing on the
|
||||
// input at the specified "index". If the input is null, it leaves
|
||||
// "result" and "offset" untouched, and returns true. If the input
|
||||
// has a GPU implementation, it will be invoked directly.
|
||||
// Otherwise, the filter will be processed in software and
|
||||
// uploaded to the GPU.
|
||||
bool filterInputGPUDeprecated(int index, SkImageFilter::Proxy* proxy,
|
||||
const SkBitmap& src, const Context&,
|
||||
SkBitmap* result, SkIPoint* offset) const;
|
||||
#endif
|
||||
|
||||
SK_TO_STRING_PUREVIRT()
|
||||
SK_DEFINE_FLATTENABLE_TYPE(SkImageFilter)
|
||||
SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
|
||||
|
||||
protected:
|
||||
class Common {
|
||||
|
@ -321,12 +274,6 @@ protected:
|
|||
|
||||
sk_sp<SkImageFilter> getInput(int index) const { return fInputs[index]; }
|
||||
|
||||
// If the caller wants a copy of the inputs, call this and it will transfer ownership
|
||||
// of the unflattened input filters to the caller. This is just a short-cut for copying
|
||||
// the inputs, calling ref() on each, and then waiting for Common's destructor to call
|
||||
// unref() on each.
|
||||
void detachInputs(SkImageFilter** inputs);
|
||||
|
||||
private:
|
||||
CropRect fCropRect;
|
||||
// most filters accept at most 2 input-filters
|
||||
|
@ -335,8 +282,6 @@ protected:
|
|||
void allocInputs(int count);
|
||||
};
|
||||
|
||||
SkImageFilter(int inputCount, SkImageFilter** inputs, const CropRect* cropRect = nullptr);
|
||||
|
||||
SkImageFilter(sk_sp<SkImageFilter>* inputs, int inputCount, const CropRect* cropRect);
|
||||
|
||||
virtual ~SkImageFilter();
|
||||
|
@ -364,15 +309,15 @@ protected:
|
|||
* Offset is the amount to translate the resulting image relative to the
|
||||
* src when it is drawn. This is an out-param.
|
||||
*
|
||||
* If the result image cannot be created, this should false, in which
|
||||
* case both the result and offset parameters will be ignored by the
|
||||
* caller.
|
||||
* If the result image cannot be created (either because of error or if, say, the result
|
||||
* is entirely clipped out), this should return nullptr.
|
||||
* Callers that affect transparent black should explicitly handle nullptr
|
||||
* results and press on. In the error case this behavior will produce a better result
|
||||
* than nothing and is necessary for the clipped out case.
|
||||
* If the return value is nullptr then offset should be ignored.
|
||||
*/
|
||||
virtual bool onFilterImageDeprecated(Proxy*, const SkBitmap& src, const Context&,
|
||||
SkBitmap* result, SkIPoint* offset) const;
|
||||
|
||||
virtual sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* src, const Context&,
|
||||
SkIPoint* offset) const;
|
||||
SkIPoint* offset) const = 0;
|
||||
|
||||
/**
|
||||
* This function recurses into its inputs with the given rect (first
|
||||
|
@ -403,12 +348,13 @@ protected:
|
|||
virtual SkIRect onFilterNodeBounds(const SkIRect&, const SkMatrix&, MapDirection) const;
|
||||
|
||||
// Helper function which invokes filter processing on the input at the
|
||||
// specified "index". If the input is null, it leaves "result" and
|
||||
// "offset" untouched, and returns true. If the input is non-null, it
|
||||
// calls filterImage() on that input, and returns true on success.
|
||||
// i.e., return !getInput(index) || getInput(index)->filterImage(...);
|
||||
bool filterInputDeprecated(int index, Proxy*, const SkBitmap& src, const Context&,
|
||||
SkBitmap* result, SkIPoint* offset) const;
|
||||
// specified "index". If the input is null, it returns "src" and leaves
|
||||
// "offset" untouched. If the input is non-null, it
|
||||
// calls filterImage() on that input, and returns the result.
|
||||
sk_sp<SkSpecialImage> filterInput(int index,
|
||||
SkSpecialImage* src,
|
||||
const Context&,
|
||||
SkIPoint* offset) const;
|
||||
|
||||
/**
|
||||
* Return true (and return a ref'd colorfilter) if this node in the DAG is just a
|
||||
|
@ -418,13 +364,18 @@ protected:
|
|||
return false;
|
||||
}
|
||||
|
||||
/** Given a "srcBounds" rect, computes destination bounds for this
|
||||
* destination bounds for this filter. "dstBounds" are computed by
|
||||
* transforming the crop rect by the context's CTM, applying it to the
|
||||
* initial bounds, and intersecting the result with the context's clip
|
||||
* bounds. "srcBounds" (if non-null) are computed by intersecting the
|
||||
* initial bounds with "dstBounds", to ensure that we never sample
|
||||
* outside of the crop rect (this restriction may be relaxed in the
|
||||
/**
|
||||
* Override this to describe the behavior of your subclass - as a leaf node. The caller will
|
||||
* take care of calling your inputs (and return false if any of them could not handle it).
|
||||
*/
|
||||
virtual bool onCanHandleComplexCTM() const { return false; }
|
||||
|
||||
/** Given a "srcBounds" rect, computes destination bounds for this filter.
|
||||
* "dstBounds" are computed by transforming the crop rect by the context's
|
||||
* CTM, applying it to the initial bounds, and intersecting the result with
|
||||
* the context's clip bounds. "srcBounds" (if non-null) are computed by
|
||||
* intersecting the initial bounds with "dstBounds", to ensure that we never
|
||||
* sample outside of the crop rect (this restriction may be relaxed in the
|
||||
* future).
|
||||
*/
|
||||
bool applyCropRect(const Context&, const SkIRect& srcBounds, SkIRect* dstBounds) const;
|
||||
|
@ -438,30 +389,9 @@ protected:
|
|||
* which are not capable of processing a smaller source bitmap into a
|
||||
* larger destination.
|
||||
*/
|
||||
bool applyCropRectDeprecated(const Context&, Proxy* proxy, const SkBitmap& src,
|
||||
SkIPoint* srcOffset, SkIRect* bounds, SkBitmap* result) const;
|
||||
|
||||
sk_sp<SkSpecialImage> applyCropRect(const Context&, SkSpecialImage* src, SkIPoint* srcOffset,
|
||||
SkIRect* bounds) const;
|
||||
|
||||
/**
|
||||
* Returns true if the filter can be expressed a single-pass
|
||||
* GrProcessor, used to process this filter on the GPU, or false if
|
||||
* not.
|
||||
*
|
||||
* If effect is non-NULL, a new GrProcessor instance is stored
|
||||
* in it. The caller assumes ownership of the stage, and it is up to the
|
||||
* caller to unref it.
|
||||
*
|
||||
* The effect can assume its vertexCoords space maps 1-to-1 with texels
|
||||
* in the texture. "matrix" is a transformation to apply to filter
|
||||
* parameters before they are used in the effect. Note that this function
|
||||
* will be called with (NULL, NULL, SkMatrix::I()) to query for support,
|
||||
* so returning "true" indicates support for all possible matrices.
|
||||
*/
|
||||
virtual bool asFragmentProcessor(GrFragmentProcessor**, GrTexture*, const SkMatrix&,
|
||||
const SkIRect& bounds) const;
|
||||
|
||||
/**
|
||||
* Creates a modified Context for use when recursing up the image filter DAG.
|
||||
* The clip bounds are adjusted to accommodate any margins that this
|
||||
|
@ -474,20 +404,19 @@ private:
|
|||
friend class SkGraphics;
|
||||
static void PurgeCache();
|
||||
|
||||
bool filterImageDeprecated(Proxy*, const SkBitmap& src, const Context&,
|
||||
SkBitmap* result, SkIPoint* offset) const;
|
||||
void init(sk_sp<SkImageFilter>* inputs, int inputCount, const CropRect* cropRect);
|
||||
|
||||
bool usesSrcInput() const { return fUsesSrcInput; }
|
||||
virtual bool affectsTransparentBlack() const { return false; }
|
||||
|
||||
typedef SkFlattenable INHERITED;
|
||||
int fInputCount;
|
||||
SkImageFilter** fInputs;
|
||||
SkAutoSTArray<2, sk_sp<SkImageFilter>> fInputs;
|
||||
|
||||
bool fUsesSrcInput;
|
||||
CropRect fCropRect;
|
||||
uint32_t fUniqueID; // Globally unique
|
||||
mutable SkTArray<Cache::Key> fCacheKeys;
|
||||
mutable SkTArray<SkImageFilterCacheKey> fCacheKeys;
|
||||
mutable SkMutex fMutex;
|
||||
typedef SkFlattenable INHERITED;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -251,7 +251,11 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
SkImageGenerator(const SkImageInfo& info);
|
||||
enum {
|
||||
kNeedNewImageUniqueID = 0
|
||||
};
|
||||
|
||||
SkImageGenerator(const SkImageInfo& info, uint32_t uniqueId = kNeedNewImageUniqueID);
|
||||
|
||||
virtual SkData* onRefEncodedData(SK_REFENCODEDDATA_CTXPARAM);
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#ifndef SkImageInfo_DEFINED
|
||||
#define SkImageInfo_DEFINED
|
||||
|
||||
#include "SkColorSpace.h"
|
||||
#include "SkMath.h"
|
||||
#include "SkRect.h"
|
||||
#include "SkSize.h"
|
||||
|
@ -105,6 +106,25 @@ static int SkColorTypeBytesPerPixel(SkColorType ct) {
|
|||
return gSize[ct];
|
||||
}
|
||||
|
||||
static int SkColorTypeShiftPerPixel(SkColorType ct) {
|
||||
static const uint8_t gShift[] = {
|
||||
0, // Unknown
|
||||
0, // Alpha_8
|
||||
1, // RGB_565
|
||||
1, // ARGB_4444
|
||||
2, // RGBA_8888
|
||||
2, // BGRA_8888
|
||||
0, // kIndex_8
|
||||
0, // kGray_8
|
||||
3, // kRGBA_F16
|
||||
};
|
||||
static_assert(SK_ARRAY_COUNT(gShift) == (size_t)(kLastEnum_SkColorType + 1),
|
||||
"size_mismatch_with_SkColorType_enum");
|
||||
|
||||
SkASSERT((size_t)ct < SK_ARRAY_COUNT(gShift));
|
||||
return gShift[ct];
|
||||
}
|
||||
|
||||
static inline size_t SkColorTypeMinRowBytes(SkColorType ct, int width) {
|
||||
return width * SkColorTypeBytesPerPixel(ct);
|
||||
}
|
||||
|
@ -114,15 +134,10 @@ static inline bool SkColorTypeIsValid(unsigned value) {
|
|||
}
|
||||
|
||||
static inline size_t SkColorTypeComputeOffset(SkColorType ct, int x, int y, size_t rowBytes) {
|
||||
int shift = 0;
|
||||
switch (SkColorTypeBytesPerPixel(ct)) {
|
||||
case 8: shift = 3; break;
|
||||
case 4: shift = 2; break;
|
||||
case 2: shift = 1; break;
|
||||
case 1: shift = 0; break;
|
||||
default: return 0;
|
||||
if (kUnknown_SkColorType == ct) {
|
||||
return 0;
|
||||
}
|
||||
return y * rowBytes + (x << shift);
|
||||
return y * rowBytes + (x << SkColorTypeShiftPerPixel(ct));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -154,11 +169,9 @@ enum SkYUVColorSpace {
|
|||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
enum SkColorProfileType {
|
||||
kLinear_SkColorProfileType,
|
||||
kSRGB_SkColorProfileType,
|
||||
|
||||
kLastEnum_SkColorProfileType = kSRGB_SkColorProfileType
|
||||
enum class SkSourceGammaTreatment {
|
||||
kRespect,
|
||||
kIgnore,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -168,61 +181,59 @@ enum SkColorProfileType {
|
|||
struct SK_API SkImageInfo {
|
||||
public:
|
||||
SkImageInfo()
|
||||
: fWidth(0)
|
||||
: fColorSpace(nullptr)
|
||||
, fWidth(0)
|
||||
, fHeight(0)
|
||||
, fColorType(kUnknown_SkColorType)
|
||||
, fAlphaType(kUnknown_SkAlphaType)
|
||||
, fProfileType(kLinear_SkColorProfileType)
|
||||
{}
|
||||
|
||||
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at,
|
||||
SkColorProfileType pt = kLinear_SkColorProfileType) {
|
||||
return SkImageInfo(width, height, ct, at, pt);
|
||||
sk_sp<SkColorSpace> cs = nullptr) {
|
||||
return SkImageInfo(width, height, ct, at, std::move(cs));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets colortype to the native ARGB32 type.
|
||||
*/
|
||||
static SkImageInfo MakeN32(int width, int height, SkAlphaType at,
|
||||
SkColorProfileType pt = kLinear_SkColorProfileType) {
|
||||
return SkImageInfo(width, height, kN32_SkColorType, at, pt);
|
||||
sk_sp<SkColorSpace> cs = nullptr) {
|
||||
return Make(width, height, kN32_SkColorType, at, cs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an ImageInfo marked as SRGB with N32 swizzle.
|
||||
*/
|
||||
static SkImageInfo MakeS32(int width, int height, SkAlphaType at);
|
||||
|
||||
/**
|
||||
* Sets colortype to the native ARGB32 type, and the alphatype to premul.
|
||||
*/
|
||||
static SkImageInfo MakeN32Premul(int width, int height,
|
||||
SkColorProfileType pt = kLinear_SkColorProfileType) {
|
||||
return SkImageInfo(width, height, kN32_SkColorType, kPremul_SkAlphaType, pt);
|
||||
static SkImageInfo MakeN32Premul(int width, int height, sk_sp<SkColorSpace> cs = nullptr) {
|
||||
return Make(width, height, kN32_SkColorType, kPremul_SkAlphaType, cs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets colortype to the native ARGB32 type, and the alphatype to premul.
|
||||
*/
|
||||
static SkImageInfo MakeN32Premul(const SkISize& size,
|
||||
SkColorProfileType pt = kLinear_SkColorProfileType) {
|
||||
return MakeN32Premul(size.width(), size.height(), pt);
|
||||
static SkImageInfo MakeN32Premul(const SkISize& size) {
|
||||
return MakeN32Premul(size.width(), size.height());
|
||||
}
|
||||
|
||||
static SkImageInfo MakeA8(int width, int height) {
|
||||
return SkImageInfo(width, height, kAlpha_8_SkColorType, kPremul_SkAlphaType,
|
||||
kLinear_SkColorProfileType);
|
||||
return Make(width, height, kAlpha_8_SkColorType, kPremul_SkAlphaType, nullptr);
|
||||
}
|
||||
|
||||
static SkImageInfo MakeUnknown(int width, int height) {
|
||||
return SkImageInfo(width, height, kUnknown_SkColorType, kUnknown_SkAlphaType,
|
||||
kLinear_SkColorProfileType);
|
||||
return Make(width, height, kUnknown_SkColorType, kUnknown_SkAlphaType, nullptr);
|
||||
}
|
||||
|
||||
static SkImageInfo MakeUnknown() {
|
||||
return SkImageInfo();
|
||||
return MakeUnknown(0, 0);
|
||||
}
|
||||
|
||||
|
||||
int width() const { return fWidth; }
|
||||
int height() const { return fHeight; }
|
||||
SkColorType colorType() const { return fColorType; }
|
||||
SkAlphaType alphaType() const { return fAlphaType; }
|
||||
SkColorProfileType profileType() const { return fProfileType; }
|
||||
SkColorSpace* colorSpace() const { return fColorSpace.get(); }
|
||||
|
||||
bool isEmpty() const { return fWidth <= 0 || fHeight <= 0; }
|
||||
|
||||
|
@ -230,32 +241,37 @@ public:
|
|||
return SkAlphaTypeIsOpaque(fAlphaType);
|
||||
}
|
||||
|
||||
bool isLinear() const { return kLinear_SkColorProfileType == fProfileType; }
|
||||
bool isSRGB() const { return kSRGB_SkColorProfileType == fProfileType; }
|
||||
|
||||
SkISize dimensions() const { return SkISize::Make(fWidth, fHeight); }
|
||||
SkIRect bounds() const { return SkIRect::MakeWH(fWidth, fHeight); }
|
||||
|
||||
bool gammaCloseToSRGB() const {
|
||||
return fColorSpace && fColorSpace->gammaCloseToSRGB();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new ImageInfo with the same colortype and alphatype as this info,
|
||||
* but with the specified width and height.
|
||||
*/
|
||||
SkImageInfo makeWH(int newWidth, int newHeight) const {
|
||||
return SkImageInfo::Make(newWidth, newHeight, fColorType, fAlphaType, fProfileType);
|
||||
return Make(newWidth, newHeight, fColorType, fAlphaType, fColorSpace);
|
||||
}
|
||||
|
||||
SkImageInfo makeAlphaType(SkAlphaType newAlphaType) const {
|
||||
return SkImageInfo::Make(fWidth, fHeight, fColorType, newAlphaType, fProfileType);
|
||||
return Make(fWidth, fHeight, fColorType, newAlphaType, fColorSpace);
|
||||
}
|
||||
|
||||
SkImageInfo makeColorType(SkColorType newColorType) const {
|
||||
return SkImageInfo::Make(fWidth, fHeight, newColorType, fAlphaType, fProfileType);
|
||||
return Make(fWidth, fHeight, newColorType, fAlphaType, fColorSpace);
|
||||
}
|
||||
|
||||
int bytesPerPixel() const {
|
||||
return SkColorTypeBytesPerPixel(fColorType);
|
||||
SkImageInfo makeColorSpace(sk_sp<SkColorSpace> cs) const {
|
||||
return Make(fWidth, fHeight, fColorType, fAlphaType, std::move(cs));
|
||||
}
|
||||
|
||||
int bytesPerPixel() const { return SkColorTypeBytesPerPixel(fColorType); }
|
||||
|
||||
int shiftPerPixel() const { return SkColorTypeShiftPerPixel(fColorType); }
|
||||
|
||||
uint64_t minRowBytes64() const {
|
||||
return sk_64_mul(fWidth, this->bytesPerPixel());
|
||||
}
|
||||
|
@ -271,10 +287,12 @@ public:
|
|||
}
|
||||
|
||||
bool operator==(const SkImageInfo& other) const {
|
||||
return 0 == memcmp(this, &other, sizeof(other));
|
||||
return fWidth == other.fWidth && fHeight == other.fHeight &&
|
||||
fColorType == other.fColorType && fAlphaType == other.fAlphaType &&
|
||||
SkColorSpace::Equals(fColorSpace.get(), other.fColorSpace.get());
|
||||
}
|
||||
bool operator!=(const SkImageInfo& other) const {
|
||||
return 0 != memcmp(this, &other, sizeof(other));
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
void unflatten(SkReadBuffer&);
|
||||
|
@ -300,32 +318,42 @@ public:
|
|||
return rowBytes >= rb;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
fColorSpace = nullptr;
|
||||
fWidth = 0;
|
||||
fHeight = 0;
|
||||
fColorType = kUnknown_SkColorType;
|
||||
fAlphaType = kUnknown_SkAlphaType;
|
||||
}
|
||||
|
||||
SkDEBUGCODE(void validate() const;)
|
||||
|
||||
private:
|
||||
sk_sp<SkColorSpace> fColorSpace;
|
||||
int fWidth;
|
||||
int fHeight;
|
||||
SkColorType fColorType;
|
||||
SkAlphaType fAlphaType;
|
||||
SkColorProfileType fProfileType;
|
||||
|
||||
SkImageInfo(int width, int height, SkColorType ct, SkAlphaType at, SkColorProfileType pt)
|
||||
: fWidth(width)
|
||||
SkImageInfo(int width, int height, SkColorType ct, SkAlphaType at, sk_sp<SkColorSpace> cs)
|
||||
: fColorSpace(std::move(cs))
|
||||
, fWidth(width)
|
||||
, fHeight(height)
|
||||
, fColorType(ct)
|
||||
, fAlphaType(at)
|
||||
, fProfileType(pt)
|
||||
{}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline bool SkColorAndProfileAreGammaCorrect(SkColorType ct, SkColorProfileType pt) {
|
||||
return kSRGB_SkColorProfileType == pt || kRGBA_F16_SkColorType == ct;
|
||||
static inline bool SkColorAndColorSpaceAreGammaCorrect(SkColorType ct, SkColorSpace* cs) {
|
||||
// Anything with a color-space attached is gamma-correct, as is F16.
|
||||
// To get legacy behavior, you need to ask for non-F16, with a nullptr color space.
|
||||
return (cs != nullptr) || kRGBA_F16_SkColorType == ct;
|
||||
}
|
||||
|
||||
static inline bool SkImageInfoIsGammaCorrect(const SkImageInfo& info) {
|
||||
return SkColorAndProfileAreGammaCorrect(info.colorType(), info.profileType());
|
||||
return SkColorAndColorSpaceAreGammaCorrect(info.colorType(), info.colorSpace());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,199 @@
|
|||
|
||||
/*
|
||||
* Copyright 2015 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkLights_DEFINED
|
||||
#define SkLights_DEFINED
|
||||
|
||||
#include "../private/SkTArray.h"
|
||||
#include "SkPoint3.h"
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
class SkReadBuffer;
|
||||
class SkWriteBuffer;
|
||||
class SkImage;
|
||||
|
||||
class SK_API SkLights : public SkRefCnt {
|
||||
public:
|
||||
class Light {
|
||||
public:
|
||||
enum LightType {
|
||||
kDirectional_LightType,
|
||||
kPoint_LightType
|
||||
};
|
||||
|
||||
Light(const Light& other)
|
||||
: fType(other.fType)
|
||||
, fColor(other.fColor)
|
||||
, fDirOrPos(other.fDirOrPos)
|
||||
, fIntensity(other.fIntensity)
|
||||
, fShadowMap(other.fShadowMap)
|
||||
, fIsRadial(other.fIsRadial) {
|
||||
}
|
||||
|
||||
Light(Light&& other)
|
||||
: fType(other.fType)
|
||||
, fColor(other.fColor)
|
||||
, fDirOrPos(other.fDirOrPos)
|
||||
, fIntensity(other.fIntensity)
|
||||
, fShadowMap(std::move(other.fShadowMap))
|
||||
, fIsRadial(other.fIsRadial) {
|
||||
}
|
||||
|
||||
static Light MakeDirectional(const SkColor3f& color, const SkVector3& dir,
|
||||
bool isRadial = false) {
|
||||
Light light(kDirectional_LightType, color, dir, isRadial);
|
||||
if (!light.fDirOrPos.normalize()) {
|
||||
light.fDirOrPos.set(0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
return light;
|
||||
}
|
||||
|
||||
static Light MakePoint(const SkColor3f& color, const SkPoint3& pos, SkScalar intensity,
|
||||
bool isRadial = false) {
|
||||
return Light(kPoint_LightType, color, pos, intensity, isRadial);
|
||||
}
|
||||
|
||||
LightType type() const { return fType; }
|
||||
const SkColor3f& color() const { return fColor; }
|
||||
const SkVector3& dir() const {
|
||||
SkASSERT(kDirectional_LightType == fType);
|
||||
return fDirOrPos;
|
||||
}
|
||||
const SkPoint3& pos() const {
|
||||
SkASSERT(kPoint_LightType == fType);
|
||||
return fDirOrPos;
|
||||
}
|
||||
SkScalar intensity() const {
|
||||
SkASSERT(kPoint_LightType == fType);
|
||||
return fIntensity;
|
||||
}
|
||||
|
||||
void setShadowMap(sk_sp<SkImage> shadowMap) {
|
||||
fShadowMap = std::move(shadowMap);
|
||||
}
|
||||
|
||||
SkImage* getShadowMap() const {
|
||||
return fShadowMap.get();
|
||||
}
|
||||
|
||||
bool isRadial() const { return fIsRadial; }
|
||||
|
||||
Light& operator= (const Light& b) {
|
||||
if (this == &b) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
fColor = b.fColor;
|
||||
fType = b.fType;
|
||||
fDirOrPos = b.fDirOrPos;
|
||||
fIntensity = b.fIntensity;
|
||||
fShadowMap = b.fShadowMap;
|
||||
fIsRadial = b.fIsRadial;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator== (const Light& b) {
|
||||
if (this == &b) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return (fColor == b.fColor) &&
|
||||
(fType == b.fType) &&
|
||||
(fDirOrPos == b.fDirOrPos) &&
|
||||
(fShadowMap == b.fShadowMap) &&
|
||||
(fIntensity == b.fIntensity) &&
|
||||
(fIsRadial == b.fIsRadial);
|
||||
}
|
||||
|
||||
bool operator!= (const Light& b) { return !(this->operator==(b)); }
|
||||
|
||||
private:
|
||||
LightType fType;
|
||||
SkColor3f fColor; // linear (unpremul) color. Range is 0..1 in each channel.
|
||||
|
||||
SkVector3 fDirOrPos; // For directional lights, holds the direction towards the
|
||||
// light (+Z is out of the screen).
|
||||
// If degenerate, it will be replaced with (0, 0, 1).
|
||||
// For point lights, holds location of point light
|
||||
|
||||
SkScalar fIntensity; // For point lights, dictates the light intensity.
|
||||
// Simply a multiplier to the final light output value.
|
||||
sk_sp<SkImage> fShadowMap;
|
||||
bool fIsRadial; // Whether the light is radial or not. Radial lights will
|
||||
// cast shadows and lights radially outwards.
|
||||
|
||||
Light(LightType type, const SkColor3f& color, const SkVector3& dirOrPos,
|
||||
SkScalar intensity = 0.0f, bool isRadial = false) {
|
||||
fType = type;
|
||||
fColor = color;
|
||||
fDirOrPos = dirOrPos;
|
||||
fIntensity = intensity;
|
||||
fIsRadial = isRadial;
|
||||
}
|
||||
};
|
||||
|
||||
class Builder {
|
||||
public:
|
||||
Builder() : fLights(new SkLights) {}
|
||||
|
||||
void add(const Light& light) {
|
||||
if (fLights) {
|
||||
fLights->fLights.push_back(light);
|
||||
}
|
||||
}
|
||||
|
||||
void add(Light&& light) {
|
||||
if (fLights) {
|
||||
fLights->fLights.push_back(std::move(light));
|
||||
}
|
||||
}
|
||||
|
||||
void setAmbientLightColor(const SkColor3f& color) {
|
||||
if (fLights) {
|
||||
fLights->fAmbientLightColor = color;
|
||||
}
|
||||
}
|
||||
|
||||
sk_sp<SkLights> finish() {
|
||||
return std::move(fLights);
|
||||
}
|
||||
|
||||
private:
|
||||
sk_sp<SkLights> fLights;
|
||||
};
|
||||
|
||||
int numLights() const {
|
||||
return fLights.count();
|
||||
}
|
||||
|
||||
const Light& light(int index) const {
|
||||
return fLights[index];
|
||||
}
|
||||
|
||||
Light& light(int index) {
|
||||
return fLights[index];
|
||||
}
|
||||
|
||||
const SkColor3f& ambientLightColor() const {
|
||||
return fAmbientLightColor;
|
||||
}
|
||||
|
||||
static sk_sp<SkLights> MakeFromBuffer(SkReadBuffer& buf);
|
||||
|
||||
void flatten(SkWriteBuffer& buf) const;
|
||||
|
||||
private:
|
||||
SkLights() {
|
||||
fAmbientLightColor.set(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
SkTArray<Light> fLights;
|
||||
SkColor3f fAmbientLightColor;
|
||||
typedef SkRefCnt INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -14,8 +14,10 @@
|
|||
#include "SkFlattenable.h"
|
||||
#include "SkMask.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkStrokeRec.h"
|
||||
|
||||
class GrClip;
|
||||
class GrContext;
|
||||
class GrDrawContext;
|
||||
class GrPaint;
|
||||
class GrRenderTarget;
|
||||
|
@ -27,7 +29,6 @@ class SkMatrix;
|
|||
class SkPath;
|
||||
class SkRasterClip;
|
||||
class SkRRect;
|
||||
class SkStrokeRec;
|
||||
|
||||
/** \class SkMaskFilter
|
||||
|
||||
|
@ -122,27 +123,26 @@ public:
|
|||
* Try to directly render a rounded rect mask filter into the target. Returns
|
||||
* true if drawing was successful.
|
||||
*/
|
||||
virtual bool directFilterRRectMaskGPU(GrTextureProvider* texProvider,
|
||||
virtual bool directFilterRRectMaskGPU(GrContext*,
|
||||
GrDrawContext* drawContext,
|
||||
GrPaint* grp,
|
||||
const GrClip&,
|
||||
const SkMatrix& viewMatrix,
|
||||
const SkStrokeRec& strokeRec,
|
||||
const SkRRect& rrect) const;
|
||||
const SkRRect& rrect,
|
||||
const SkRRect& devRRect) const;
|
||||
|
||||
/**
|
||||
* This function is used to implement filters that require an explicit src mask. It should only
|
||||
* be called if canFilterMaskGPU returned true and the maskRect param should be the output from
|
||||
* that call. canOverwriteSrc indicates whether the implementation may treat src as a scratch
|
||||
* texture and overwrite its contents. When true it is also legal to return src as the result.
|
||||
* that call.
|
||||
* Implementations are free to get the GrContext from the src texture in order to create
|
||||
* additional textures and perform multiple passes.
|
||||
*/
|
||||
virtual bool filterMaskGPU(GrTexture* src,
|
||||
const SkMatrix& ctm,
|
||||
const SkRect& maskRect,
|
||||
GrTexture** result,
|
||||
bool canOverwriteSrc) const;
|
||||
const SkIRect& maskRect,
|
||||
GrTexture** result) const;
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -228,14 +228,14 @@ private:
|
|||
This method is not exported to java.
|
||||
*/
|
||||
bool filterPath(const SkPath& devPath, const SkMatrix& ctm, const SkRasterClip&, SkBlitter*,
|
||||
SkPaint::Style) const;
|
||||
SkStrokeRec::InitStyle) const;
|
||||
|
||||
/** Helper method that, given a roundRect in device space, will rasterize it into a kA8_Format
|
||||
mask and then call filterMask(). If this returns true, the specified blitter will be called
|
||||
to render that mask. Returns false if filterMask() returned false.
|
||||
*/
|
||||
bool filterRRect(const SkRRect& devRRect, const SkMatrix& ctm, const SkRasterClip&,
|
||||
SkBlitter*, SkPaint::Style style) const;
|
||||
SkBlitter*) const;
|
||||
|
||||
typedef SkFlattenable INHERITED;
|
||||
};
|
||||
|
|
|
@ -52,13 +52,6 @@ static inline int32_t SkMulDiv(int32_t numer1, int32_t numer2, int32_t denom) {
|
|||
return sk_64_asS32(tmp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes (numer1 << shift) / denom in full 64 intermediate precision.
|
||||
* It is an error for denom to be 0. There is no special handling if
|
||||
* the result overflows 32bits.
|
||||
*/
|
||||
int32_t SkDivBits(int32_t numer, int32_t denom, int shift);
|
||||
|
||||
/**
|
||||
* Return the integer square root of value, with a bias of bitBias
|
||||
*/
|
||||
|
@ -68,35 +61,6 @@ int32_t SkSqrtBits(int32_t value, int bitBias);
|
|||
*/
|
||||
#define SkSqrt32(n) SkSqrtBits(n, 15)
|
||||
|
||||
//! Returns the number of leading zero bits (0...32)
|
||||
int SkCLZ_portable(uint32_t);
|
||||
|
||||
#ifndef SkCLZ
|
||||
#if defined(_MSC_VER)
|
||||
#include <intrin.h>
|
||||
|
||||
static inline int SkCLZ(uint32_t mask) {
|
||||
if (mask) {
|
||||
DWORD index;
|
||||
_BitScanReverse(&index, mask);
|
||||
// Suppress this bogus /analyze warning. The check for non-zero
|
||||
// guarantees that _BitScanReverse will succeed.
|
||||
#pragma warning(suppress : 6102) // Using 'index' from failed function call
|
||||
return index ^ 0x1F;
|
||||
} else {
|
||||
return 32;
|
||||
}
|
||||
}
|
||||
#elif defined(SK_CPU_ARM32) || defined(__GNUC__) || defined(__clang__)
|
||||
static inline int SkCLZ(uint32_t mask) {
|
||||
// __builtin_clz(0) is undefined, so we have to detect that case.
|
||||
return mask ? __builtin_clz(mask) : 32;
|
||||
}
|
||||
#else
|
||||
#define SkCLZ(x) SkCLZ_portable(x)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Returns (value < 0 ? 0 : value) efficiently (i.e. no compares or branches)
|
||||
*/
|
||||
|
@ -122,35 +86,11 @@ static inline int SkClampMax(int value, int max) {
|
|||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the smallest power-of-2 that is >= the specified value. If value
|
||||
* is already a power of 2, then it is returned unchanged. It is undefined
|
||||
* if value is <= 0.
|
||||
*/
|
||||
static inline int SkNextPow2(int value) {
|
||||
SkASSERT(value > 0);
|
||||
return 1 << (32 - SkCLZ(value - 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the log2 of the specified value, were that value to be rounded up
|
||||
* to the next power of 2. It is undefined to pass 0. Examples:
|
||||
* SkNextLog2(1) -> 0
|
||||
* SkNextLog2(2) -> 1
|
||||
* SkNextLog2(3) -> 2
|
||||
* SkNextLog2(4) -> 2
|
||||
* SkNextLog2(5) -> 3
|
||||
*/
|
||||
static inline int SkNextLog2(uint32_t value) {
|
||||
SkASSERT(value != 0);
|
||||
return 32 - SkCLZ(value - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if value is a power of 2. Does not explicitly check for
|
||||
* value <= 0.
|
||||
*/
|
||||
template <typename T> inline bool SkIsPow2(T value) {
|
||||
template <typename T> constexpr inline bool SkIsPow2(T value) {
|
||||
return (value & (value - 1)) == 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ public:
|
|||
|
||||
/** Returns true if will map a rectangle to another rectangle. This can be
|
||||
true if the matrix is identity, scale-only, or rotates a multiple of
|
||||
90 degrees.
|
||||
90 degrees, or mirrors in x or y.
|
||||
*/
|
||||
bool rectStaysRect() const {
|
||||
if (fTypeMask & kUnknown_Mask) {
|
||||
|
@ -561,6 +561,12 @@ public:
|
|||
this->mapPoints(dst, 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps a rect to another rect, asserting (in debug mode) that the matrix only contains
|
||||
* scale and translate elements. If it contains other elements, the results are undefined.
|
||||
*/
|
||||
void mapRectScaleTranslate(SkRect* dst, const SkRect& src) const;
|
||||
|
||||
/** Return the mean radius of a circle after it has been mapped by
|
||||
this matrix. NOTE: in perspective this value assumes the circle
|
||||
has its center at the origin.
|
||||
|
@ -704,6 +710,37 @@ public:
|
|||
this->setTypeMask(kUnknown_Mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the matrix to be scale + post-translate.
|
||||
*/
|
||||
void setScaleTranslate(SkScalar sx, SkScalar sy, SkScalar tx, SkScalar ty) {
|
||||
fMat[kMScaleX] = sx;
|
||||
fMat[kMSkewX] = 0;
|
||||
fMat[kMTransX] = tx;
|
||||
|
||||
fMat[kMSkewY] = 0;
|
||||
fMat[kMScaleY] = sy;
|
||||
fMat[kMTransY] = ty;
|
||||
|
||||
fMat[kMPersp0] = 0;
|
||||
fMat[kMPersp1] = 0;
|
||||
fMat[kMPersp2] = 1;
|
||||
|
||||
unsigned mask = 0;
|
||||
if (sx != 1 || sy != 1) {
|
||||
mask |= kScale_Mask;
|
||||
}
|
||||
if (tx || ty) {
|
||||
mask |= kTranslate_Mask;
|
||||
}
|
||||
this->setTypeMask(mask | kRectStaysRect_Mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Are all elements of the matrix finite?
|
||||
*/
|
||||
bool isFinite() const { return SkScalarsAreFinite(fMat, 9); }
|
||||
|
||||
private:
|
||||
enum {
|
||||
/** Set if the matrix will map a rectangle to another rectangle. This
|
||||
|
@ -736,35 +773,8 @@ private:
|
|||
SkScalar fMat[9];
|
||||
mutable uint32_t fTypeMask;
|
||||
|
||||
/** Are all elements of the matrix finite?
|
||||
*/
|
||||
bool isFinite() const { return SkScalarsAreFinite(fMat, 9); }
|
||||
|
||||
static void ComputeInv(SkScalar dst[9], const SkScalar src[9], double invDet, bool isPersp);
|
||||
|
||||
void setScaleTranslate(SkScalar sx, SkScalar sy, SkScalar tx, SkScalar ty) {
|
||||
fMat[kMScaleX] = sx;
|
||||
fMat[kMSkewX] = 0;
|
||||
fMat[kMTransX] = tx;
|
||||
|
||||
fMat[kMSkewY] = 0;
|
||||
fMat[kMScaleY] = sy;
|
||||
fMat[kMTransY] = ty;
|
||||
|
||||
fMat[kMPersp0] = 0;
|
||||
fMat[kMPersp1] = 0;
|
||||
fMat[kMPersp2] = 1;
|
||||
|
||||
unsigned mask = 0;
|
||||
if (sx != 1 || sy != 1) {
|
||||
mask |= kScale_Mask;
|
||||
}
|
||||
if (tx || ty) {
|
||||
mask |= kTranslate_Mask;
|
||||
}
|
||||
this->setTypeMask(mask | kRectStaysRect_Mask);
|
||||
}
|
||||
|
||||
uint8_t computeTypeMask() const;
|
||||
uint8_t computePerspectiveTypeMask() const;
|
||||
|
||||
|
@ -833,6 +843,7 @@ private:
|
|||
static const MapPtsProc gMapPtsProcs[];
|
||||
|
||||
friend class SkPerspIter;
|
||||
friend class SkMatrixPriv;
|
||||
};
|
||||
SK_END_REQUIRE_DENSE
|
||||
|
||||
|
|
|
@ -136,8 +136,15 @@ public:
|
|||
kIdentity_Constructor
|
||||
};
|
||||
|
||||
SkMatrix44(Uninitialized_Constructor) { }
|
||||
SkMatrix44(Identity_Constructor) { this->setIdentity(); }
|
||||
SkMatrix44(Uninitialized_Constructor) {}
|
||||
|
||||
constexpr SkMatrix44(Identity_Constructor)
|
||||
: fMat{{ 1, 0, 0, 0, },
|
||||
{ 0, 1, 0, 0, },
|
||||
{ 0, 0, 1, 0, },
|
||||
{ 0, 0, 0, 1, }}
|
||||
, fTypeMask(kIdentity_Mask)
|
||||
{}
|
||||
|
||||
SK_ATTR_DEPRECATED("use the constructors that take an enum")
|
||||
SkMatrix44() { this->setIdentity(); }
|
||||
|
@ -281,6 +288,10 @@ public:
|
|||
* array. The given array must have room for exactly 16 entries. Whenever
|
||||
* possible, they will try to use memcpy rather than an entry-by-entry
|
||||
* copy.
|
||||
*
|
||||
* Col major indicates that consecutive elements of columns will be stored
|
||||
* contiguously in memory. Row major indicates that consecutive elements
|
||||
* of rows will be stored contiguously in memory.
|
||||
*/
|
||||
void asColMajorf(float[]) const;
|
||||
void asColMajord(double[]) const;
|
||||
|
@ -291,6 +302,11 @@ public:
|
|||
* array. The given array must have room for exactly 16 entries. Whenever
|
||||
* possible, they will try to use memcpy rather than an entry-by-entry
|
||||
* copy.
|
||||
*
|
||||
* Col major indicates that input memory will be treated as if consecutive
|
||||
* elements of columns are stored contiguously in memory. Row major
|
||||
* indicates that input memory will be treated as if consecutive elements
|
||||
* of rows are stored contiguously in memory.
|
||||
*/
|
||||
void setColMajorf(const float[]);
|
||||
void setColMajord(const double[]);
|
||||
|
@ -306,10 +322,12 @@ public:
|
|||
#endif
|
||||
|
||||
/* This sets the top-left of the matrix and clears the translation and
|
||||
* perspective components (with [3][3] set to 1). */
|
||||
* perspective components (with [3][3] set to 1). mXY is interpreted
|
||||
* as the matrix entry at col = X, row = Y. */
|
||||
void set3x3(SkMScalar m00, SkMScalar m01, SkMScalar m02,
|
||||
SkMScalar m10, SkMScalar m11, SkMScalar m12,
|
||||
SkMScalar m20, SkMScalar m21, SkMScalar m22);
|
||||
void set3x3RowMajorf(const float[]);
|
||||
|
||||
void setTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz);
|
||||
void preTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz);
|
||||
|
@ -429,6 +447,7 @@ public:
|
|||
double determinant() const;
|
||||
|
||||
private:
|
||||
/* This is indexed by [col][row]. */
|
||||
SkMScalar fMat[4][4];
|
||||
mutable unsigned fTypeMask;
|
||||
|
||||
|
@ -438,6 +457,9 @@ private:
|
|||
kAllPublic_Masks = 0xF
|
||||
};
|
||||
|
||||
void as3x4RowMajorf(float[]) const;
|
||||
void set3x4RowMajorf(const float[]);
|
||||
|
||||
SkMScalar transX() const { return fMat[3][0]; }
|
||||
SkMScalar transY() const { return fMat[3][1]; }
|
||||
SkMScalar transZ() const { return fMat[3][2]; }
|
||||
|
@ -468,6 +490,8 @@ private:
|
|||
inline bool isTriviallyIdentity() const {
|
||||
return 0 == fTypeMask;
|
||||
}
|
||||
|
||||
friend class SkColorSpace;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -5,5 +5,5 @@
|
|||
* found in the LICENSE file.
|
||||
*/
|
||||
#ifndef SK_MILESTONE
|
||||
#define SK_MILESTONE 51
|
||||
#define SK_MILESTONE 55
|
||||
#endif
|
||||
|
|
|
@ -8,11 +8,14 @@
|
|||
#ifndef SkPaint_DEFINED
|
||||
#define SkPaint_DEFINED
|
||||
|
||||
#include "SkBlendMode.h"
|
||||
#include "SkColor.h"
|
||||
#include "SkFilterQuality.h"
|
||||
#include "SkMatrix.h"
|
||||
#include "SkXfermode.h"
|
||||
|
||||
//#define SK_SUPPORT_LEGACY_XFERMODE_OBJECT
|
||||
|
||||
class SkAutoDescriptor;
|
||||
class SkAutoGlyphCache;
|
||||
class SkColorFilter;
|
||||
|
@ -30,8 +33,10 @@ class SkPath;
|
|||
class SkPathEffect;
|
||||
struct SkPoint;
|
||||
class SkRasterizer;
|
||||
struct SkScalerContextEffects;
|
||||
class SkShader;
|
||||
class SkSurfaceProps;
|
||||
class SkTextBlob;
|
||||
class SkTypeface;
|
||||
|
||||
#define kBicubicFilterBitmap_Flag kHighQualityFilterBitmap_Flag
|
||||
|
@ -408,9 +413,10 @@ public:
|
|||
kRound_Cap, //!< begin/end contours with a semi-circle extension
|
||||
kSquare_Cap, //!< begin/end contours with a half square extension
|
||||
|
||||
kCapCount,
|
||||
kLast_Cap = kSquare_Cap,
|
||||
kDefault_Cap = kButt_Cap
|
||||
};
|
||||
static constexpr int kCapCount = kLast_Cap + 1;
|
||||
|
||||
/** Join enum specifies the settings for the paint's strokejoin. This is
|
||||
the treatment that is applied to corners in paths and rectangles.
|
||||
|
@ -420,9 +426,10 @@ public:
|
|||
kRound_Join, //!< connect path segments with a round join
|
||||
kBevel_Join, //!< connect path segments with a flat bevel join
|
||||
|
||||
kJoinCount,
|
||||
kLast_Join = kBevel_Join,
|
||||
kDefault_Join = kMiter_Join
|
||||
};
|
||||
static constexpr int kJoinCount = kLast_Join + 1;
|
||||
|
||||
/** Return the paint's stroke cap type, controlling how the start and end
|
||||
of stroked lines and paths are treated.
|
||||
|
@ -521,12 +528,13 @@ public:
|
|||
#endif
|
||||
void setColorFilter(sk_sp<SkColorFilter>);
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_XFERMODE_OBJECT
|
||||
/** Get the paint's xfermode object.
|
||||
<p />
|
||||
The xfermode's reference count is not affected.
|
||||
@return the paint's xfermode (or NULL)
|
||||
*/
|
||||
SkXfermode* getXfermode() const { return fXfermode.get(); }
|
||||
SkXfermode* getXfermode() const;
|
||||
|
||||
/** Set or clear the xfermode object.
|
||||
<p />
|
||||
|
@ -548,6 +556,11 @@ public:
|
|||
the paint's xfermode is set to null.
|
||||
*/
|
||||
SkXfermode* setXfermodeMode(SkXfermode::Mode);
|
||||
#endif
|
||||
|
||||
SkBlendMode getBlendMode() const { return (SkBlendMode)fBlendMode; }
|
||||
bool isSrcOver() const { return (SkBlendMode)fBlendMode == SkBlendMode::kSrcOver; }
|
||||
void setBlendMode(SkBlendMode mode) { fBlendMode = (unsigned)mode; }
|
||||
|
||||
/** Get the paint's patheffect object.
|
||||
<p />
|
||||
|
@ -613,8 +626,10 @@ public:
|
|||
paint
|
||||
@return typeface
|
||||
*/
|
||||
SkTypeface* setTypeface(SkTypeface* typeface);
|
||||
void setTypeface(sk_sp<SkTypeface>);
|
||||
#ifdef SK_SUPPORT_LEGACY_TYPEFACE_PTR
|
||||
SkTypeface* setTypeface(SkTypeface* typeface);
|
||||
#endif
|
||||
|
||||
/** Get the paint's rasterizer (or NULL).
|
||||
<p />
|
||||
|
@ -647,19 +662,18 @@ public:
|
|||
* Return the paint's SkDrawLooper (if any). Does not affect the looper's
|
||||
* reference count.
|
||||
*/
|
||||
SkDrawLooper* getLooper() const { return fLooper.get(); }
|
||||
|
||||
SkDrawLooper* getDrawLooper() const { return fDrawLooper.get(); }
|
||||
SkDrawLooper* getLooper() const { return fDrawLooper.get(); }
|
||||
/**
|
||||
* Set or clear the looper object.
|
||||
* <p />
|
||||
* Pass NULL to clear any previous looper.
|
||||
* As a convenience, the parameter passed is also returned.
|
||||
* If a previous looper exists in the paint, its reference count is
|
||||
* decremented. If looper is not NULL, its reference count is
|
||||
* incremented.
|
||||
* @param looper May be NULL. The new looper to be installed in the paint.
|
||||
* @return looper
|
||||
*/
|
||||
void setDrawLooper(sk_sp<SkDrawLooper>);
|
||||
#ifdef SK_SUPPORT_LEGACY_MINOR_EFFECT_PTR
|
||||
SkDrawLooper* setLooper(SkDrawLooper* looper);
|
||||
#endif
|
||||
|
@ -816,7 +830,7 @@ public:
|
|||
is returned.
|
||||
*/
|
||||
int textToGlyphs(const void* text, size_t byteLength,
|
||||
uint16_t glyphs[]) const;
|
||||
SkGlyphID glyphs[]) const;
|
||||
|
||||
/** Return true if all of the specified text has a corresponding non-zero
|
||||
glyph ID. If any of the code-points in the text are not supported in
|
||||
|
@ -831,7 +845,7 @@ public:
|
|||
to zero. Note: this does not look at the text-encoding setting in the
|
||||
paint, only at the typeface.
|
||||
*/
|
||||
void glyphsToUnichars(const uint16_t glyphs[], int count, SkUnichar text[]) const;
|
||||
void glyphsToUnichars(const SkGlyphID glyphs[], int count, SkUnichar text[]) const;
|
||||
|
||||
/** Return the number of drawable units in the specified text buffer.
|
||||
This looks at the current TextEncoding field of the paint. If you also
|
||||
|
@ -959,6 +973,40 @@ public:
|
|||
int getPosTextIntercepts(const void* text, size_t length, const SkPoint pos[],
|
||||
const SkScalar bounds[2], SkScalar* intervals) const;
|
||||
|
||||
/** Return the number of intervals that intersect the intercept along the axis of the advance.
|
||||
* The return count is zero or a multiple of two, and is at most the number of glyphs * 2 in
|
||||
* string. The caller may pass nullptr for intervals to determine the size of the interval
|
||||
* array, or may conservatively pre-allocate an array with length * 2 entries. The computed
|
||||
* intervals are cached by glyph to improve performance for multiple calls.
|
||||
* This permits constructing an underline that skips the descenders.
|
||||
*
|
||||
* @param text The text.
|
||||
* @param length Number of bytes of text.
|
||||
* @param xpos Array of x-positions, used to position each character.
|
||||
* @param constY The shared Y coordinate for all of the positions.
|
||||
* @param bounds The lower and upper line parallel to the advance.
|
||||
* @param array If not null, the glyph bounds contained by the advance parallel lines.
|
||||
*
|
||||
* @return The number of intersections, which may be zero.
|
||||
*/
|
||||
int getPosTextHIntercepts(const void* text, size_t length, const SkScalar xpos[],
|
||||
SkScalar constY, const SkScalar bounds[2], SkScalar* intervals) const;
|
||||
|
||||
/** Return the number of intervals that intersect the intercept along the axis of the advance.
|
||||
* The return count is zero or a multiple of two, and is at most the number of glyphs * 2 in
|
||||
* text blob. The caller may pass nullptr for intervals to determine the size of the interval
|
||||
* array. The computed intervals are cached by glyph to improve performance for multiple calls.
|
||||
* This permits constructing an underline that skips the descenders.
|
||||
*
|
||||
* @param blob The text blob.
|
||||
* @param bounds The lower and upper line parallel to the advance.
|
||||
* @param array If not null, the glyph bounds contained by the advance parallel lines.
|
||||
*
|
||||
* @return The number of intersections, which may be zero.
|
||||
*/
|
||||
int getTextBlobIntercepts(const SkTextBlob* blob, const SkScalar bounds[2],
|
||||
SkScalar* intervals) const;
|
||||
|
||||
/**
|
||||
* Return a rectangle that represents the union of the bounds of all
|
||||
* of the glyphs, but each one positioned at (0,0). This may be conservatively large, and
|
||||
|
@ -1051,11 +1099,10 @@ private:
|
|||
sk_sp<SkTypeface> fTypeface;
|
||||
sk_sp<SkPathEffect> fPathEffect;
|
||||
sk_sp<SkShader> fShader;
|
||||
sk_sp<SkXfermode> fXfermode;
|
||||
sk_sp<SkMaskFilter> fMaskFilter;
|
||||
sk_sp<SkColorFilter> fColorFilter;
|
||||
sk_sp<SkRasterizer> fRasterizer;
|
||||
sk_sp<SkDrawLooper> fLooper;
|
||||
sk_sp<SkDrawLooper> fDrawLooper;
|
||||
sk_sp<SkImageFilter> fImageFilter;
|
||||
|
||||
SkScalar fTextSize;
|
||||
|
@ -1064,6 +1111,7 @@ private:
|
|||
SkColor fColor;
|
||||
SkScalar fWidth;
|
||||
SkScalar fMiterLimit;
|
||||
uint32_t fBlendMode; // just need 5-6 bits for SkXfermode::Mode
|
||||
union {
|
||||
struct {
|
||||
// all of these bitfields should add up to 32
|
||||
|
@ -1080,28 +1128,38 @@ private:
|
|||
uint32_t fBitfieldsUInt;
|
||||
};
|
||||
|
||||
GlyphCacheProc getGlyphCacheProc(bool needFullMetrics) const;
|
||||
static GlyphCacheProc GetGlyphCacheProc(TextEncoding encoding,
|
||||
bool isDevKern,
|
||||
bool needFullMetrics);
|
||||
|
||||
SkScalar measure_text(SkGlyphCache*, const char* text, size_t length,
|
||||
int* count, SkRect* bounds) const;
|
||||
|
||||
enum class FakeGamma {
|
||||
Off = 0, On
|
||||
enum ScalerContextFlags : uint32_t {
|
||||
kNone_ScalerContextFlags = 0,
|
||||
|
||||
kFakeGamma_ScalerContextFlag = 1 << 0,
|
||||
kBoostContrast_ScalerContextFlag = 1 << 1,
|
||||
|
||||
kFakeGammaAndBoostContrast_ScalerContextFlags =
|
||||
kFakeGamma_ScalerContextFlag | kBoostContrast_ScalerContextFlag,
|
||||
};
|
||||
|
||||
/*
|
||||
* Allocs an SkDescriptor on the heap and return it to the caller as a refcnted
|
||||
* SkData. Caller is responsible for managing the lifetime of this object.
|
||||
*/
|
||||
void getScalerContextDescriptor(SkAutoDescriptor*, const SkSurfaceProps& surfaceProps,
|
||||
FakeGamma fakeGamma, const SkMatrix*) const;
|
||||
void getScalerContextDescriptor(SkScalerContextEffects*, SkAutoDescriptor*,
|
||||
const SkSurfaceProps& surfaceProps,
|
||||
uint32_t scalerContextFlags, const SkMatrix*) const;
|
||||
|
||||
SkGlyphCache* detachCache(const SkSurfaceProps* surfaceProps, FakeGamma fakeGamma,
|
||||
SkGlyphCache* detachCache(const SkSurfaceProps* surfaceProps, uint32_t scalerContextFlags,
|
||||
const SkMatrix*) const;
|
||||
|
||||
void descriptorProc(const SkSurfaceProps* surfaceProps, FakeGamma fakeGamma,
|
||||
void descriptorProc(const SkSurfaceProps* surfaceProps, uint32_t scalerContextFlags,
|
||||
const SkMatrix* deviceMatrix,
|
||||
void (*proc)(SkTypeface*, const SkDescriptor*, void*),
|
||||
void (*proc)(SkTypeface*, const SkScalerContextEffects&,
|
||||
const SkDescriptor*, void*),
|
||||
void* context) const;
|
||||
|
||||
/*
|
||||
|
|
|
@ -26,6 +26,13 @@ class SkWStream;
|
|||
*/
|
||||
class SK_API SkPath {
|
||||
public:
|
||||
enum Direction {
|
||||
/** clockwise direction for adding closed contours */
|
||||
kCW_Direction,
|
||||
/** counter-clockwise direction for adding closed contours */
|
||||
kCCW_Direction,
|
||||
};
|
||||
|
||||
SkPath();
|
||||
SkPath(const SkPath&);
|
||||
~SkPath();
|
||||
|
@ -166,24 +173,45 @@ public:
|
|||
*
|
||||
* @param rect returns the bounding rect of this oval. It's a circle
|
||||
* if the height and width are the same.
|
||||
*
|
||||
* @param dir is the oval CCW (or CW if false).
|
||||
* @param start indicates where the contour starts on the oval (see
|
||||
* SkPath::addOval for intepretation of the index).
|
||||
* @return true if this path is an oval.
|
||||
* Tracking whether a path is an oval is considered an
|
||||
* optimization for performance and so some paths that are in
|
||||
* fact ovals can report false.
|
||||
*/
|
||||
bool isOval(SkRect* rect) const { return fPathRef->isOval(rect); }
|
||||
bool isOval(SkRect* rect, Direction* dir = nullptr,
|
||||
unsigned* start = nullptr) const {
|
||||
bool isCCW = false;
|
||||
bool result = fPathRef->isOval(rect, &isCCW, start);
|
||||
if (dir && result) {
|
||||
*dir = isCCW ? kCCW_Direction : kCW_Direction;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Returns true if the path is a round rect.
|
||||
*
|
||||
* @param rrect Returns the bounding rect and radii of this round rect.
|
||||
* @param dir is the rrect CCW (or CW if false).
|
||||
* @param start indicates where the contour starts on the rrect (see
|
||||
* SkPath::addRRect for intepretation of the index).
|
||||
*
|
||||
* @return true if this path is a round rect.
|
||||
* Tracking whether a path is a round rect is considered an
|
||||
* optimization for performance and so some paths that are in
|
||||
* fact round rects can report false.
|
||||
*/
|
||||
bool isRRect(SkRRect* rrect) const { return fPathRef->isRRect(rrect); }
|
||||
bool isRRect(SkRRect* rrect, Direction* dir = nullptr,
|
||||
unsigned* start = nullptr) const {
|
||||
bool isCCW = false;
|
||||
bool result = fPathRef->isRRect(rrect, &isCCW, start);
|
||||
if (dir && result) {
|
||||
*dir = isCCW ? kCCW_Direction : kCW_Direction;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Clear any lines and curves from the path, making it empty. This frees up
|
||||
internal storage associated with those segments.
|
||||
|
@ -526,13 +554,6 @@ public:
|
|||
kLarge_ArcSize,
|
||||
};
|
||||
|
||||
enum Direction {
|
||||
/** clockwise direction for adding closed contours */
|
||||
kCW_Direction,
|
||||
/** counter-clockwise direction for adding closed contours */
|
||||
kCCW_Direction,
|
||||
};
|
||||
|
||||
/**
|
||||
* Append an elliptical arc from the current point in the format used by SVG.
|
||||
* The center of the ellipse is computed to satisfy the constraints below.
|
||||
|
@ -717,7 +738,8 @@ public:
|
|||
void addOval(const SkRect& oval, Direction dir, unsigned start);
|
||||
|
||||
/**
|
||||
* Add a closed circle contour to the path
|
||||
* Add a closed circle contour to the path. The circle contour begins at
|
||||
* the right-most point (as though 1 were passed to addOval's 'start' param).
|
||||
*
|
||||
* @param x The x-coordinate of the center of a circle to add as a
|
||||
* closed contour to the path
|
||||
|
|
|
@ -66,7 +66,7 @@ public:
|
|||
fSize.set(SK_Scalar1, SK_Scalar1);
|
||||
// 'asPoints' needs to initialize/fill-in 'fClipRect' if it sets
|
||||
// the kUseClip flag
|
||||
};
|
||||
}
|
||||
~PointData() {
|
||||
delete [] fPoints;
|
||||
}
|
||||
|
@ -118,6 +118,8 @@ public:
|
|||
|
||||
struct DashInfo {
|
||||
DashInfo() : fIntervals(NULL), fCount(0), fPhase(0) {}
|
||||
DashInfo(SkScalar* intervals, int32_t count, SkScalar phase)
|
||||
: fIntervals(intervals), fCount(count), fPhase(phase) {}
|
||||
|
||||
SkScalar* fIntervals; //!< Length of on/off intervals for dashed lines
|
||||
// Even values represent ons, and odds offs
|
||||
|
@ -153,7 +155,7 @@ private:
|
|||
including flattening them. It does nothing in filterPath, and is only useful
|
||||
for managing the lifetimes of its two arguments.
|
||||
*/
|
||||
class SkPairPathEffect : public SkPathEffect {
|
||||
class SK_API SkPairPathEffect : public SkPathEffect {
|
||||
protected:
|
||||
SkPairPathEffect(sk_sp<SkPathEffect> pe0, sk_sp<SkPathEffect> pe1);
|
||||
|
||||
|
@ -174,7 +176,7 @@ private:
|
|||
This subclass of SkPathEffect composes its two arguments, to create
|
||||
a compound pathEffect.
|
||||
*/
|
||||
class SkComposePathEffect : public SkPairPathEffect {
|
||||
class SK_API SkComposePathEffect : public SkPairPathEffect {
|
||||
public:
|
||||
/** Construct a pathEffect whose effect is to apply first the inner pathEffect
|
||||
and the the outer pathEffect (e.g. outer(inner(path)))
|
||||
|
@ -224,7 +226,7 @@ private:
|
|||
This subclass of SkPathEffect applies two pathEffects, one after the other.
|
||||
Its filterPath() returns true if either of the effects succeeded.
|
||||
*/
|
||||
class SkSumPathEffect : public SkPairPathEffect {
|
||||
class SK_API SkSumPathEffect : public SkPairPathEffect {
|
||||
public:
|
||||
/** Construct a pathEffect whose effect is to apply two effects, in sequence.
|
||||
(e.g. first(path) + second(path))
|
||||
|
|
|
@ -95,7 +95,8 @@ private:
|
|||
SkScalar fDistance; // total distance up to this point
|
||||
unsigned fPtIndex; // index into the fPts array
|
||||
unsigned fTValue : 30;
|
||||
unsigned fType : 2;
|
||||
unsigned fType : 2; // actually the enum SkSegType
|
||||
// See SkPathMeasurePriv.h
|
||||
|
||||
SkScalar getScalarT() const;
|
||||
};
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#ifndef SkPathRef_DEFINED
|
||||
#define SkPathRef_DEFINED
|
||||
|
||||
#include "../private/SkAtomics.h"
|
||||
#include "../private/SkTDArray.h"
|
||||
#include "SkMatrix.h"
|
||||
#include "SkPoint.h"
|
||||
|
@ -35,7 +36,7 @@ class SkWBuffer;
|
|||
* logical verb or the last verb in memory).
|
||||
*/
|
||||
|
||||
class SK_API SkPathRef : public ::SkRefCnt {
|
||||
class SK_API SkPathRef final : public SkNVRefCnt<SkPathRef> {
|
||||
public:
|
||||
class Editor {
|
||||
public:
|
||||
|
@ -57,11 +58,11 @@ public:
|
|||
SkPoint* atPoint(int i) {
|
||||
SkASSERT((unsigned) i < (unsigned) fPathRef->fPointCnt);
|
||||
return this->points() + i;
|
||||
};
|
||||
}
|
||||
const SkPoint* atPoint(int i) const {
|
||||
SkASSERT((unsigned) i < (unsigned) fPathRef->fPointCnt);
|
||||
return this->points() + i;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the verb and allocates space for the number of points indicated by the verb. The
|
||||
|
@ -99,9 +100,13 @@ public:
|
|||
*/
|
||||
SkPathRef* pathRef() { return fPathRef; }
|
||||
|
||||
void setIsOval(bool isOval) { fPathRef->setIsOval(isOval); }
|
||||
void setIsOval(bool isOval, bool isCCW, unsigned start) {
|
||||
fPathRef->setIsOval(isOval, isCCW, start);
|
||||
}
|
||||
|
||||
void setIsRRect(bool isRRect) { fPathRef->setIsRRect(isRRect); }
|
||||
void setIsRRect(bool isRRect, bool isCCW, unsigned start) {
|
||||
fPathRef->setIsRRect(isRRect, isCCW, start);
|
||||
}
|
||||
|
||||
void setBounds(const SkRect& rect) { fPathRef->setBounds(rect); }
|
||||
|
||||
|
@ -163,23 +168,42 @@ public:
|
|||
*
|
||||
* @param rect returns the bounding rect of this oval. It's a circle
|
||||
* if the height and width are the same.
|
||||
* @param isCCW is the oval CCW (or CW if false).
|
||||
* @param start indicates where the contour starts on the oval (see
|
||||
* SkPath::addOval for intepretation of the index).
|
||||
*
|
||||
* @return true if this path is an oval.
|
||||
* Tracking whether a path is an oval is considered an
|
||||
* optimization for performance and so some paths that are in
|
||||
* fact ovals can report false.
|
||||
*/
|
||||
bool isOval(SkRect* rect) const {
|
||||
if (fIsOval && rect) {
|
||||
*rect = this->getBounds();
|
||||
bool isOval(SkRect* rect, bool* isCCW, unsigned* start) const {
|
||||
if (fIsOval) {
|
||||
if (rect) {
|
||||
*rect = this->getBounds();
|
||||
}
|
||||
if (isCCW) {
|
||||
*isCCW = SkToBool(fRRectOrOvalIsCCW);
|
||||
}
|
||||
if (start) {
|
||||
*start = fRRectOrOvalStartIdx;
|
||||
}
|
||||
}
|
||||
|
||||
return SkToBool(fIsOval);
|
||||
}
|
||||
|
||||
bool isRRect(SkRRect* rrect) const {
|
||||
if (fIsRRect && rrect) {
|
||||
*rrect = this->getRRect();
|
||||
bool isRRect(SkRRect* rrect, bool* isCCW, unsigned* start) const {
|
||||
if (fIsRRect) {
|
||||
if (rrect) {
|
||||
*rrect = this->getRRect();
|
||||
}
|
||||
if (isCCW) {
|
||||
*isCCW = SkToBool(fRRectOrOvalIsCCW);
|
||||
}
|
||||
if (start) {
|
||||
*start = fRRectOrOvalStartIdx;
|
||||
}
|
||||
}
|
||||
return SkToBool(fIsRRect);
|
||||
}
|
||||
|
@ -219,7 +243,7 @@ public:
|
|||
*/
|
||||
static void Rewind(SkAutoTUnref<SkPathRef>* pathRef);
|
||||
|
||||
virtual ~SkPathRef();
|
||||
~SkPathRef();
|
||||
int countPoints() const { SkDEBUGCODE(this->validate();) return fPointCnt; }
|
||||
int countVerbs() const { SkDEBUGCODE(this->validate();) return fVerbCnt; }
|
||||
int countWeights() const { SkDEBUGCODE(this->validate();) return fConicWeights.count(); }
|
||||
|
@ -291,10 +315,12 @@ public:
|
|||
|
||||
private:
|
||||
enum SerializationOffsets {
|
||||
kIsRRect_SerializationShift = 26, // requires 1 bit
|
||||
kIsFinite_SerializationShift = 25, // requires 1 bit
|
||||
kIsOval_SerializationShift = 24, // requires 1 bit
|
||||
kSegmentMask_SerializationShift = 0 // requires 4 bits
|
||||
kRRectOrOvalStartIdx_SerializationShift = 28, // requires 3 bits
|
||||
kRRectOrOvalIsCCW_SerializationShift = 27, // requires 1 bit
|
||||
kIsRRect_SerializationShift = 26, // requires 1 bit
|
||||
kIsFinite_SerializationShift = 25, // requires 1 bit
|
||||
kIsOval_SerializationShift = 24, // requires 1 bit
|
||||
kSegmentMask_SerializationShift = 0 // requires 4 bits
|
||||
};
|
||||
|
||||
SkPathRef() {
|
||||
|
@ -308,6 +334,9 @@ private:
|
|||
fSegmentMask = 0;
|
||||
fIsOval = false;
|
||||
fIsRRect = false;
|
||||
// The next two values don't matter unless fIsOval or fIsRRect are true.
|
||||
fRRectOrOvalIsCCW = false;
|
||||
fRRectOrOvalStartIdx = 0xAC;
|
||||
SkDEBUGCODE(fEditorsAttached = 0;)
|
||||
SkDEBUGCODE(this->validate();)
|
||||
}
|
||||
|
@ -453,9 +482,17 @@ private:
|
|||
*/
|
||||
friend SkPathRef* sk_create_empty_pathref();
|
||||
|
||||
void setIsOval(bool isOval) { fIsOval = isOval; }
|
||||
void setIsOval(bool isOval, bool isCCW, unsigned start) {
|
||||
fIsOval = isOval;
|
||||
fRRectOrOvalIsCCW = isCCW;
|
||||
fRRectOrOvalStartIdx = start;
|
||||
}
|
||||
|
||||
void setIsRRect(bool isRRect) { fIsRRect = isRRect; }
|
||||
void setIsRRect(bool isRRect, bool isCCW, unsigned start) {
|
||||
fIsRRect = isRRect;
|
||||
fRRectOrOvalIsCCW = isCCW;
|
||||
fRRectOrOvalStartIdx = start;
|
||||
}
|
||||
|
||||
// called only by the editor. Note that this is not a const function.
|
||||
SkPoint* getPoints() {
|
||||
|
@ -498,11 +535,14 @@ private:
|
|||
|
||||
SkBool8 fIsOval;
|
||||
SkBool8 fIsRRect;
|
||||
// Both the circle and rrect special cases have a notion of direction and starting point
|
||||
// The next two variables store that information for either.
|
||||
SkBool8 fRRectOrOvalIsCCW;
|
||||
uint8_t fRRectOrOvalStartIdx;
|
||||
uint8_t fSegmentMask;
|
||||
|
||||
friend class PathRefTest_Private;
|
||||
friend class ForceIsRRect_Private; // unit test isRRect
|
||||
typedef SkRefCnt INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -16,6 +16,9 @@ class GrContext;
|
|||
class SkBigPicture;
|
||||
class SkBitmap;
|
||||
class SkCanvas;
|
||||
class SkData;
|
||||
class SkImage;
|
||||
class SkImageDeserializer;
|
||||
class SkPath;
|
||||
class SkPictureData;
|
||||
class SkPixelSerializer;
|
||||
|
@ -49,6 +52,7 @@ public:
|
|||
*/
|
||||
typedef bool (*InstallPixelRefProc)(const void* src, size_t length, SkBitmap* dst);
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_PICTUREINSTALLPIXELREF
|
||||
/**
|
||||
* Recreate a picture that was serialized into a stream.
|
||||
* @param SkStream Serialized picture data. Ownership is unchanged by this call.
|
||||
|
@ -58,18 +62,22 @@ public:
|
|||
* invalid.
|
||||
*/
|
||||
static sk_sp<SkPicture> MakeFromStream(SkStream*, InstallPixelRefProc proc);
|
||||
static sk_sp<SkPicture> MakeFromStream(SkStream* stream, std::nullptr_t) {
|
||||
return MakeFromStream(stream);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Recreate a picture that was serialized into a stream.
|
||||
*
|
||||
* Any serialized images in the stream will be passed to
|
||||
* SkImageGenerator::NewFromEncoded.
|
||||
*
|
||||
* @param SkStream Serialized picture data. Ownership is unchanged by this call.
|
||||
* @return A new SkPicture representing the serialized data, or NULL if the stream is
|
||||
* invalid.
|
||||
* Any serialized images in the stream will be passed the image-deserializer, or if that is
|
||||
* null, to the default deserializer that will call SkImage::MakeFromEncoded().
|
||||
*/
|
||||
static sk_sp<SkPicture> MakeFromStream(SkStream*, SkImageDeserializer*);
|
||||
static sk_sp<SkPicture> MakeFromStream(SkStream*);
|
||||
static sk_sp<SkPicture> MakeFromData(const void* data, size_t size,
|
||||
SkImageDeserializer* = nullptr);
|
||||
static sk_sp<SkPicture> MakeFromData(const SkData* data, SkImageDeserializer* = nullptr);
|
||||
|
||||
/**
|
||||
* Recreate a picture that was serialized into a buffer. If the creation requires bitmap
|
||||
|
@ -116,10 +124,16 @@ public:
|
|||
uint32_t uniqueID() const;
|
||||
|
||||
/**
|
||||
* Serialize to a stream. If non NULL, serializer will be used to serialize
|
||||
* bitmaps and images in the picture.
|
||||
* Serialize the picture to SkData. If non nullptr, pixel-serializer will be used to
|
||||
* customize how images reference by the picture are serialized/compressed.
|
||||
*/
|
||||
void serialize(SkWStream*, SkPixelSerializer* = NULL) const;
|
||||
sk_sp<SkData> serialize(SkPixelSerializer* = nullptr) const;
|
||||
|
||||
/**
|
||||
* Serialize to a stream. If non nullptr, pixel-serializer will be used to
|
||||
* customize how images reference by the picture are serialized/compressed.
|
||||
*/
|
||||
void serialize(SkWStream*, SkPixelSerializer* = nullptr) const;
|
||||
|
||||
/**
|
||||
* Serialize to a buffer.
|
||||
|
@ -139,10 +153,6 @@ public:
|
|||
*/
|
||||
virtual int approximateOpCount() const = 0;
|
||||
|
||||
/** Return true if this picture contains text.
|
||||
*/
|
||||
virtual bool hasText() const = 0;
|
||||
|
||||
/** Returns the approximate byte size of this picture, not including large ref'd objects. */
|
||||
virtual size_t approximateBytesUsed() const = 0;
|
||||
|
||||
|
@ -157,8 +167,10 @@ public:
|
|||
static bool InternalOnly_StreamIsSKP(SkStream*, SkPictInfo*);
|
||||
static bool InternalOnly_BufferIsSKP(SkReadBuffer*, SkPictInfo*);
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_PICTURE_GPUVETO
|
||||
/** Return true if the picture is suitable for rendering on the GPU. */
|
||||
bool suitableForGpuRasterization(GrContext*, const char** whyNot = NULL) const;
|
||||
#endif
|
||||
|
||||
// Sent via SkMessageBus from destructor.
|
||||
struct DeletionMessage { int32_t fUniqueID; }; // TODO: -> uint32_t?
|
||||
|
@ -190,10 +202,11 @@ private:
|
|||
template <typename> friend class SkMiniPicture;
|
||||
|
||||
void serialize(SkWStream*, SkPixelSerializer*, SkRefCntSet* typefaces) const;
|
||||
static sk_sp<SkPicture> MakeFromStream(SkStream*, InstallPixelRefProc, SkTypefacePlayback*);
|
||||
static sk_sp<SkPicture> MakeFromStream(SkStream*, SkImageDeserializer*, SkTypefacePlayback*);
|
||||
friend class SkPictureData;
|
||||
|
||||
virtual int numSlowPaths() const = 0;
|
||||
friend class SkPictureGpuAnalyzer;
|
||||
friend struct SkPathCounter;
|
||||
|
||||
// V35: Store SkRect (rather then width & height) in header
|
||||
|
@ -206,10 +219,16 @@ private:
|
|||
// V42: Added a bool to SkPictureShader serialization to indicate did-we-serialize-a-picture?
|
||||
// V43: Added DRAW_IMAGE and DRAW_IMAGE_RECT opt codes to serialized data
|
||||
// V44: Move annotations from paint to drawAnnotation
|
||||
// V45: Add invNormRotation to SkLightingShader.
|
||||
// V46: Add drawTextRSXform
|
||||
// V47: Add occluder rect to SkBlurMaskFilter
|
||||
// V48: Read and write extended SkTextBlobs.
|
||||
// V49: Gradients serialized as SkColor4f + SkColorSpace
|
||||
// V50: SkXfermode -> SkBlendMode
|
||||
|
||||
// Only SKPs within the min/current picture version range (inclusive) can be read.
|
||||
static const uint32_t MIN_PICTURE_VERSION = 35; // Produced by Chrome M39.
|
||||
static const uint32_t CURRENT_PICTURE_VERSION = 44;
|
||||
static const uint32_t CURRENT_PICTURE_VERSION = 50;
|
||||
|
||||
static_assert(MIN_PICTURE_VERSION <= 41,
|
||||
"Remove kFontFileName and related code from SkFontDescriptor.cpp.");
|
||||
|
@ -219,9 +238,17 @@ private:
|
|||
|
||||
static_assert(MIN_PICTURE_VERSION <= 43,
|
||||
"Remove SkBitmapSourceDeserializer.");
|
||||
|
||||
|
||||
static_assert(MIN_PICTURE_VERSION <= 45,
|
||||
"Remove decoding of old SkTypeface::Style from SkFontDescriptor.cpp.");
|
||||
|
||||
static_assert(MIN_PICTURE_VERSION <= 48,
|
||||
"Remove legacy gradient deserialization code from SkGradientShader.cpp.");
|
||||
|
||||
static bool IsValidPictInfo(const SkPictInfo& info);
|
||||
static sk_sp<SkPicture> Forwardport(const SkPictInfo&, const SkPictureData*);
|
||||
static sk_sp<SkPicture> Forwardport(const SkPictInfo&,
|
||||
const SkPictureData*,
|
||||
SkReadBuffer* buffer);
|
||||
|
||||
SkPictInfo createHeader() const;
|
||||
SkPictureData* backport() const;
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkPictureAnalyzer_DEFINED
|
||||
#define SkPictureAnalyzer_DEFINED
|
||||
|
||||
#include "SkCanvas.h"
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkRegion.h"
|
||||
#include "SkTypes.h"
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
#include "GrContext.h"
|
||||
|
||||
class SkPath;
|
||||
class SkPicture;
|
||||
|
||||
/** \class SkPictureGpuAnalyzer
|
||||
|
||||
Gathers GPU-related statistics for one or more SkPictures.
|
||||
*/
|
||||
class SK_API SkPictureGpuAnalyzer final : public SkNoncopyable {
|
||||
public:
|
||||
explicit SkPictureGpuAnalyzer(sk_sp<GrContextThreadSafeProxy> = nullptr);
|
||||
explicit SkPictureGpuAnalyzer(const sk_sp<SkPicture>& picture,
|
||||
sk_sp<GrContextThreadSafeProxy> = nullptr);
|
||||
|
||||
/**
|
||||
* Process the given picture and accumulate its stats.
|
||||
*/
|
||||
void analyzePicture(const SkPicture*);
|
||||
|
||||
/**
|
||||
* Process an explicit clipPath op.
|
||||
*/
|
||||
void analyzeClipPath(const SkPath&, SkCanvas::ClipOp, bool doAntiAlias);
|
||||
|
||||
/**
|
||||
* Reset all accumulated stats.
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/**
|
||||
* Returns true if the analyzed pictures are suitable for rendering on the GPU.
|
||||
*/
|
||||
bool suitableForGpuRasterization(const char** whyNot = nullptr) const;
|
||||
|
||||
/**
|
||||
* Returns the number of commands which are slow to draw on the GPU, capped at the predicate
|
||||
* max.
|
||||
*/
|
||||
uint32_t numSlowGpuCommands() { return fNumSlowPaths; }
|
||||
|
||||
private:
|
||||
uint32_t fNumSlowPaths;
|
||||
|
||||
typedef SkNoncopyable INHERITED;
|
||||
};
|
||||
|
||||
#endif // SK_SUPPORT_GPU
|
||||
|
||||
#endif // SkPictureAnalyzer_DEFINED
|
|
@ -19,6 +19,7 @@ namespace android {
|
|||
};
|
||||
#endif
|
||||
|
||||
class GrContext;
|
||||
class SkCanvas;
|
||||
class SkDrawable;
|
||||
class SkPictureRecord;
|
||||
|
@ -31,13 +32,13 @@ public:
|
|||
~SkPictureRecorder();
|
||||
|
||||
enum RecordFlags {
|
||||
// This flag indicates that, if some BHH is being computed, saveLayer
|
||||
// information should also be extracted at the same time.
|
||||
kComputeSaveLayerInfo_RecordFlag = 0x01,
|
||||
|
||||
// If you call drawPicture() or drawDrawable() on the recording canvas, this flag forces
|
||||
// that object to playback its contents immediately rather than reffing the object.
|
||||
kPlaybackDrawPicture_RecordFlag = 0x02,
|
||||
kPlaybackDrawPicture_RecordFlag = 1 << 0,
|
||||
};
|
||||
|
||||
enum FinishFlags {
|
||||
kReturnNullForEmpty_FinishFlag = 1 << 0, // no draw-ops will return nullptr
|
||||
};
|
||||
|
||||
/** Returns the canvas that records the drawing commands.
|
||||
|
@ -72,7 +73,7 @@ public:
|
|||
* reflect their current state, but will not contain a live reference to the drawables
|
||||
* themselves.
|
||||
*/
|
||||
sk_sp<SkPicture> finishRecordingAsPicture();
|
||||
sk_sp<SkPicture> finishRecordingAsPicture(uint32_t endFlags = 0);
|
||||
|
||||
/**
|
||||
* Signal that the caller is done recording, and update the cull rect to use for bounding
|
||||
|
@ -83,7 +84,8 @@ public:
|
|||
* and subsequent culling operations.
|
||||
* @return the picture containing the recorded content.
|
||||
*/
|
||||
sk_sp<SkPicture> finishRecordingAsPictureWithCull(const SkRect& cullRect);
|
||||
sk_sp<SkPicture> finishRecordingAsPictureWithCull(const SkRect& cullRect,
|
||||
uint32_t endFlags = 0);
|
||||
|
||||
/**
|
||||
* Signal that the caller is done recording. This invalidates the canvas returned by
|
||||
|
@ -95,7 +97,7 @@ public:
|
|||
* and therefore this drawable will reflect the current state of those nested drawables anytime
|
||||
* it is drawn or a new picture is snapped from it (by calling drawable->newPictureSnapshot()).
|
||||
*/
|
||||
sk_sp<SkDrawable> finishRecordingAsDrawable();
|
||||
sk_sp<SkDrawable> finishRecordingAsDrawable(uint32_t endFlags = 0);
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_PICTURE_PTR
|
||||
SkPicture* SK_WARN_UNUSED_RESULT endRecordingAsPicture() {
|
||||
|
|
|
@ -206,10 +206,6 @@ public:
|
|||
|
||||
bool requestLock(const LockRequest&, LockResult*);
|
||||
|
||||
/** Are we really wrapping a texture instead of a bitmap?
|
||||
*/
|
||||
virtual GrTexture* getTexture() { return NULL; }
|
||||
|
||||
/**
|
||||
* If this can efficiently return YUV data, this should return true.
|
||||
* Otherwise this returns false and does not modify any of the parameters.
|
||||
|
@ -238,20 +234,6 @@ public:
|
|||
/** Populates dst with the pixels of this pixelRef, converting them to colorType. */
|
||||
bool readPixels(SkBitmap* dst, SkColorType colorType, const SkIRect* subset = NULL);
|
||||
|
||||
/**
|
||||
* Makes a deep copy of this PixelRef, respecting the requested config.
|
||||
* @param colorType Desired colortype.
|
||||
* @param profileType Desired colorprofiletype.
|
||||
* @param subset Subset of this PixelRef to copy. Must be fully contained within the bounds of
|
||||
* of this PixelRef.
|
||||
* @return A new SkPixelRef, or NULL if either there is an error (e.g. the destination could
|
||||
* not be created with the given config), or this PixelRef does not support deep
|
||||
* copies.
|
||||
*/
|
||||
virtual SkPixelRef* deepCopy(SkColorType, SkColorProfileType, const SkIRect* /*subset*/) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Register a listener that may be called the next time our generation ID changes.
|
||||
//
|
||||
// We'll only call the listener if we're confident that we are the only SkPixelRef with this
|
||||
|
@ -404,6 +386,7 @@ private:
|
|||
void setImmutableWithID(uint32_t genID);
|
||||
friend class SkImage_Gpu;
|
||||
friend class SkImageCacherator;
|
||||
friend class SkSpecialImage_Gpu;
|
||||
|
||||
typedef SkRefCnt INHERITED;
|
||||
};
|
||||
|
|
|
@ -44,6 +44,9 @@ public:
|
|||
this->reset(info, NULL, 0, NULL);
|
||||
}
|
||||
|
||||
// overrides the colorspace in the SkImageInfo of the pixmap
|
||||
void setColorSpace(sk_sp<SkColorSpace>);
|
||||
|
||||
/**
|
||||
* If supported, set this pixmap to point to the pixels in the specified mask and return true.
|
||||
* On failure, return false and set this pixmap to empty.
|
||||
|
@ -80,7 +83,7 @@ public:
|
|||
* Return the shift amount per pixel (i.e. 0 for 1-byte per pixel, 1 for 2-bytes per pixel
|
||||
* colortypes, 2 for 4-bytes per pixel colortypes). Return 0 for kUnknown_SkColorType.
|
||||
*/
|
||||
int shiftPerPixel() const { return fInfo.bytesPerPixel() >> 1; }
|
||||
int shiftPerPixel() const { return fInfo.shiftPerPixel(); }
|
||||
|
||||
uint64_t getSize64() const { return sk_64_mul(fInfo.height(), fRowBytes); }
|
||||
uint64_t getSafeSize64() const { return fInfo.getSafeSize64(fRowBytes); }
|
||||
|
@ -141,6 +144,9 @@ public:
|
|||
// Writable versions
|
||||
|
||||
void* writable_addr() const { return const_cast<void*>(fPixels); }
|
||||
void* writable_addr(int x, int y) const {
|
||||
return const_cast<void*>(this->addr(x, y));
|
||||
}
|
||||
uint8_t* writable_addr8(int x, int y) const {
|
||||
return const_cast<uint8_t*>(this->addr8(x, y));
|
||||
}
|
||||
|
|
|
@ -549,4 +549,8 @@ struct SK_API SkPoint {
|
|||
|
||||
typedef SkPoint SkVector;
|
||||
|
||||
static inline bool SkPointsAreFinite(const SkPoint array[], int count) {
|
||||
return SkScalarsAreFinite(&array[0].fX, count << 1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -14,6 +14,14 @@
|
|||
# define SK_BUILD_FOR_WIN
|
||||
#endif
|
||||
|
||||
#if !defined(SK_DEBUG) && !defined(SK_RELEASE)
|
||||
#ifdef NDEBUG
|
||||
#define SK_RELEASE
|
||||
#else
|
||||
#define SK_DEBUG
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(SK_DEBUG) && defined(SK_RELEASE)
|
||||
# error "cannot define both SK_DEBUG and SK_RELEASE"
|
||||
#elif !defined(SK_DEBUG) && !defined(SK_RELEASE)
|
||||
|
@ -78,6 +86,14 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
|
||||
#define SK_VECTORCALL __vectorcall
|
||||
#elif defined(SK_CPU_ARM32) && defined(SK_ARM_HAS_NEON)
|
||||
#define SK_VECTORCALL __attribute__((pcs("aapcs-vfp")))
|
||||
#else
|
||||
#define SK_VECTORCALL
|
||||
#endif
|
||||
|
||||
#if !defined(SK_SUPPORT_GPU)
|
||||
# define SK_SUPPORT_GPU 1
|
||||
#endif
|
||||
|
@ -107,26 +123,6 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef SK_BUILD_FOR_WIN
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_IS_MEAN_WAS_LOCALLY_DEFINED
|
||||
# endif
|
||||
# ifndef NOMINMAX
|
||||
# define NOMINMAX
|
||||
# define NOMINMAX_WAS_LOCALLY_DEFINED
|
||||
# endif
|
||||
#
|
||||
# include <windows.h>
|
||||
#
|
||||
# ifdef WIN32_IS_MEAN_WAS_LOCALLY_DEFINED
|
||||
# undef WIN32_IS_MEAN_WAS_LOCALLY_DEFINED
|
||||
# undef WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# ifdef NOMINMAX_WAS_LOCALLY_DEFINED
|
||||
# undef NOMINMAX_WAS_LOCALLY_DEFINED
|
||||
# undef NOMINMAX
|
||||
# endif
|
||||
#
|
||||
# ifndef SK_A32_SHIFT
|
||||
# define SK_A32_SHIFT 24
|
||||
# define SK_R32_SHIFT 16
|
||||
|
@ -145,10 +141,10 @@
|
|||
#endif
|
||||
|
||||
#ifndef SK_ABORT
|
||||
# define SK_ABORT(msg) \
|
||||
# define SK_ABORT(message) \
|
||||
do { \
|
||||
SkNO_RETURN_HINT(); \
|
||||
SkDebugf("%s:%d: fatal error: \"%s\"\n", __FILE__, __LINE__, #msg); \
|
||||
SkDebugf("%s:%d: fatal error: \"%s\"\n", __FILE__, __LINE__, message); \
|
||||
SK_DUMP_GOOGLE3_STACK(); \
|
||||
sk_abort_no_print(); \
|
||||
} while (false)
|
||||
|
@ -249,7 +245,11 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(SK_UNUSED)
|
||||
# define SK_UNUSED SK_ATTRIBUTE(unused)
|
||||
# if defined(_MSC_VER)
|
||||
# define SK_UNUSED __pragma(warning(suppress:4189))
|
||||
# else
|
||||
# define SK_UNUSED SK_ATTRIBUTE(unused)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(SK_ATTR_DEPRECATED)
|
||||
|
@ -279,6 +279,18 @@
|
|||
# endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* If your judgment is better than the compiler's (i.e. you've profiled it),
|
||||
* you can use SK_NEVER_INLINE to prevent inlining.
|
||||
*/
|
||||
#if !defined(SK_NEVER_INLINE)
|
||||
# if defined(SK_BUILD_FOR_WIN)
|
||||
# define SK_NEVER_INLINE __declspec(noinline)
|
||||
# else
|
||||
# define SK_NEVER_INLINE SK_ATTRIBUTE(noinline)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE1
|
||||
|
@ -330,12 +342,8 @@
|
|||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(SK_GAMMA_EXPONENT) && defined(SK_GAMMA_SRGB)
|
||||
# error "cannot define both SK_GAMMA_EXPONENT and SK_GAMMA_SRGB"
|
||||
#elif defined(SK_GAMMA_SRGB)
|
||||
# define SK_GAMMA_EXPONENT (0.0f)
|
||||
#elif !defined(SK_GAMMA_EXPONENT)
|
||||
# define SK_GAMMA_EXPONENT (2.2f)
|
||||
#if !defined(SK_GAMMA_EXPONENT)
|
||||
#define SK_GAMMA_EXPONENT (0.0f) // SRGB
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
@ -346,6 +354,12 @@
|
|||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(SK_HISTOGRAM_ENUMERATION) && defined(SK_HISTOGRAM_BOOLEAN)
|
||||
# define SK_HISTOGRAMS_ENABLED 1
|
||||
#else
|
||||
# define SK_HISTOGRAMS_ENABLED 0
|
||||
#endif
|
||||
|
||||
#ifndef SK_HISTOGRAM_BOOLEAN
|
||||
# define SK_HISTOGRAM_BOOLEAN(name, value)
|
||||
#endif
|
||||
|
|
|
@ -24,14 +24,14 @@
|
|||
#include "TargetConditionals.h"
|
||||
#endif
|
||||
|
||||
#if defined(WIN32) || defined(__SYMBIAN32__)
|
||||
#if defined(_WIN32) || defined(__SYMBIAN32__)
|
||||
#define SK_BUILD_FOR_WIN32
|
||||
#elif defined(ANDROID)
|
||||
#elif defined(ANDROID) || defined(__ANDROID__)
|
||||
#define SK_BUILD_FOR_ANDROID
|
||||
#elif defined(linux) || defined(__linux) || defined(__FreeBSD__) || \
|
||||
defined(__OpenBSD__) || defined(__sun) || defined(__NetBSD__) || \
|
||||
defined(__DragonFly__) || defined(__GLIBC__) || defined(__GNU__) || \
|
||||
defined(__unix__)
|
||||
defined(__DragonFly__) || defined(__Fuchsia__) || \
|
||||
defined(__GLIBC__) || defined(__GNU__) || defined(__unix__)
|
||||
#define SK_BUILD_FOR_UNIX
|
||||
#elif TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
|
||||
#define SK_BUILD_FOR_IOS
|
||||
|
@ -52,14 +52,6 @@
|
|||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(SK_DEBUG) && !defined(SK_RELEASE)
|
||||
#ifdef NDEBUG
|
||||
#define SK_RELEASE
|
||||
#else
|
||||
#define SK_DEBUG
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef SK_BUILD_FOR_WIN32
|
||||
#if !defined(SK_RESTRICT)
|
||||
#define SK_RESTRICT __restrict
|
||||
|
@ -69,8 +61,6 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(SK_RESTRICT)
|
||||
#define SK_RESTRICT __restrict__
|
||||
#endif
|
||||
|
@ -118,8 +108,12 @@
|
|||
#define SK_CPU_SSE_LEVEL_AVX 51
|
||||
#define SK_CPU_SSE_LEVEL_AVX2 52
|
||||
|
||||
#ifdef SK_BUILD_FOR_IOS
|
||||
#define SK_CPU_SSE_LEVEL 0 // We're tired of fighting with opts/ and iOS simulator.
|
||||
// When targetting iOS and using gyp to generate the build files, it is not
|
||||
// possible to select files to build depending on the architecture (i.e. it
|
||||
// is not possible to use hand optimized assembly implementation). In that
|
||||
// configuration SK_BUILD_NO_OPTS is defined. Remove optimisation then.
|
||||
#ifdef SK_BUILD_NO_OPTS
|
||||
#define SK_CPU_SSE_LEVEL 0
|
||||
#endif
|
||||
|
||||
// Are we in GCC?
|
||||
|
@ -190,35 +184,41 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
// Disable ARM64 optimizations for iOS due to complications regarding gyp and iOS.
|
||||
#if defined(__aarch64__) && !defined(SK_BUILD_FOR_IOS)
|
||||
#if defined(__aarch64__) && !defined(SK_BUILD_NO_OPTS)
|
||||
#define SK_CPU_ARM64
|
||||
#endif
|
||||
|
||||
// All 64-bit ARM chips have NEON. Many 32-bit ARM chips do too.
|
||||
// TODO: Why don't we want NEON on iOS?
|
||||
#if !defined(SK_ARM_HAS_NEON) && !defined(SK_BUILD_FOR_IOS) && (defined(__ARM_NEON__) || defined(__ARM_NEON))
|
||||
#if !defined(SK_ARM_HAS_NEON) && !defined(SK_BUILD_NO_OPTS) && (defined(__ARM_NEON__) || defined(__ARM_NEON))
|
||||
#define SK_ARM_HAS_NEON
|
||||
#endif
|
||||
|
||||
// Really this __APPLE__ check shouldn't be necessary, but it seems that Apple's Clang defines
|
||||
// __ARM_FEATURE_CRC32 for -arch arm64, even though their chips don't support those instructions!
|
||||
#if defined(__ARM_FEATURE_CRC32) && !defined(__APPLE__)
|
||||
#define SK_ARM_HAS_CRC32
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(SKIA_IMPLEMENTATION)
|
||||
#define SKIA_IMPLEMENTATION 0
|
||||
#endif
|
||||
|
||||
#if defined(SKIA_DLL)
|
||||
#if defined(WIN32)
|
||||
#if SKIA_IMPLEMENTATION
|
||||
#define SK_API __declspec(dllexport)
|
||||
#if !defined(SK_API)
|
||||
#if defined(SKIA_DLL)
|
||||
#if defined(_MSC_VER)
|
||||
#if SKIA_IMPLEMENTATION
|
||||
#define SK_API __declspec(dllexport)
|
||||
#else
|
||||
#define SK_API __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define SK_API __declspec(dllimport)
|
||||
#define SK_API __attribute__((visibility("default")))
|
||||
#endif
|
||||
#else
|
||||
#define SK_API __attribute__((visibility("default")))
|
||||
#define SK_API
|
||||
#endif
|
||||
#else
|
||||
#define SK_API
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -16,7 +16,6 @@ class SkMatrix;
|
|||
|
||||
// Path forward:
|
||||
// core work
|
||||
// add validate method (all radii positive, all radii sums < rect size, etc.)
|
||||
// add contains(SkRect&) - for clip stack
|
||||
// add contains(SkRRect&) - for clip stack
|
||||
// add heart rect computation (max rect inside RR)
|
||||
|
@ -47,6 +46,10 @@ class SkMatrix;
|
|||
*/
|
||||
class SK_API SkRRect {
|
||||
public:
|
||||
SkRRect() { /* unititialized */ }
|
||||
SkRRect(const SkRRect&) = default;
|
||||
SkRRect& operator=(const SkRRect&) = default;
|
||||
|
||||
/**
|
||||
* Enum to capture the various possible subtypes of RR. Accessed
|
||||
* by type(). The subtypes become progressively less restrictive.
|
||||
|
@ -86,7 +89,7 @@ public:
|
|||
* Returns the RR's sub type.
|
||||
*/
|
||||
Type getType() const {
|
||||
SkDEBUGCODE(this->validate();)
|
||||
SkASSERT(this->isValid());
|
||||
return static_cast<Type>(fType);
|
||||
}
|
||||
|
||||
|
@ -120,7 +123,7 @@ public:
|
|||
memset(fRadii, 0, sizeof(fRadii));
|
||||
fType = kEmpty_Type;
|
||||
|
||||
SkDEBUGCODE(this->validate();)
|
||||
SkASSERT(this->isValid());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -138,7 +141,13 @@ public:
|
|||
memset(fRadii, 0, sizeof(fRadii));
|
||||
fType = kRect_Type;
|
||||
|
||||
SkDEBUGCODE(this->validate();)
|
||||
SkASSERT(this->isValid());
|
||||
}
|
||||
|
||||
static SkRRect MakeEmpty() {
|
||||
SkRRect rr;
|
||||
rr.setEmpty();
|
||||
return rr;
|
||||
}
|
||||
|
||||
static SkRRect MakeRect(const SkRect& r) {
|
||||
|
@ -146,7 +155,7 @@ public:
|
|||
rr.setRect(r);
|
||||
return rr;
|
||||
}
|
||||
|
||||
|
||||
static SkRRect MakeOval(const SkRect& oval) {
|
||||
SkRRect rr;
|
||||
rr.setOval(oval);
|
||||
|
@ -180,7 +189,7 @@ public:
|
|||
}
|
||||
fType = kOval_Type;
|
||||
|
||||
SkDEBUGCODE(this->validate();)
|
||||
SkASSERT(this->isValid());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -268,13 +277,17 @@ public:
|
|||
fRect.offset(dx, dy);
|
||||
}
|
||||
|
||||
SkRRect SK_WARN_UNUSED_RESULT makeOffset(SkScalar dx, SkScalar dy) const {
|
||||
return SkRRect(fRect.makeOffset(dx, dy), fRadii, fType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if 'rect' is wholy inside the RR, and both
|
||||
* are not empty.
|
||||
*/
|
||||
bool contains(const SkRect& rect) const;
|
||||
|
||||
SkDEBUGCODE(void validate() const;)
|
||||
bool isValid() const;
|
||||
|
||||
enum {
|
||||
kSizeInMemory = 12 * sizeof(SkScalar)
|
||||
|
@ -316,6 +329,11 @@ public:
|
|||
void dumpHex() const { this->dump(true); }
|
||||
|
||||
private:
|
||||
SkRRect(const SkRect& rect, const SkVector radii[4], int32_t type)
|
||||
: fRect(rect)
|
||||
, fRadii{radii[0], radii[1], radii[2], radii[3]}
|
||||
, fType(type) {}
|
||||
|
||||
SkRect fRect;
|
||||
// Radii order is UL, UR, LR, LL. Use Corner enum to index into fRadii[]
|
||||
SkVector fRadii[4];
|
||||
|
|
|
@ -25,7 +25,7 @@ public:
|
|||
* Return the logical length of the data owned/shared by this buffer. It may be stored in
|
||||
* multiple contiguous blocks, accessible via the iterator.
|
||||
*/
|
||||
size_t size() const { return fUsed; }
|
||||
size_t size() const { return fAvailable; }
|
||||
|
||||
class SK_API Iter {
|
||||
public:
|
||||
|
@ -53,22 +53,25 @@ public:
|
|||
private:
|
||||
const SkBufferBlock* fBlock;
|
||||
size_t fRemaining;
|
||||
const SkROBuffer* fBuffer;
|
||||
};
|
||||
|
||||
private:
|
||||
SkROBuffer(const SkBufferHead* head, size_t used);
|
||||
SkROBuffer(const SkBufferHead* head, size_t available, const SkBufferBlock* fTail);
|
||||
virtual ~SkROBuffer();
|
||||
|
||||
const SkBufferHead* fHead;
|
||||
const size_t fUsed;
|
||||
const SkBufferHead* fHead;
|
||||
const size_t fAvailable;
|
||||
const SkBufferBlock* fTail;
|
||||
|
||||
friend class SkRWBuffer;
|
||||
};
|
||||
|
||||
/**
|
||||
* Accumulates bytes of memory that are "appended" to it, growing internal storage as needed.
|
||||
* The growth is done such that at any time, a RBuffer or StreamAsset can be snapped off, which
|
||||
* can see the previously stored bytes, but which will be unaware of any future writes.
|
||||
* The growth is done such that at any time in the writer's thread, an RBuffer or StreamAsset
|
||||
* can be snapped off (and safely passed to another thread). The RBuffer/StreamAsset snapshot
|
||||
* can see the previously stored bytes, but will be unaware of any future writes.
|
||||
*/
|
||||
class SK_API SkRWBuffer {
|
||||
public:
|
||||
|
@ -76,8 +79,15 @@ public:
|
|||
~SkRWBuffer();
|
||||
|
||||
size_t size() const { return fTotalUsed; }
|
||||
void append(const void* buffer, size_t length);
|
||||
void* append(size_t length);
|
||||
|
||||
/**
|
||||
* Append |length| bytes from |buffer|.
|
||||
*
|
||||
* If the caller knows in advance how much more data they are going to append, they can
|
||||
* pass a |reserve| hint (representing the number of upcoming bytes *in addition* to the
|
||||
* current append), to minimize the number of internal allocations.
|
||||
*/
|
||||
void append(const void* buffer, size_t length, size_t reserve = 0);
|
||||
|
||||
SkROBuffer* newRBufferSnapshot() const;
|
||||
SkStreamAsset* newStreamSnapshot() const;
|
||||
|
|
|
@ -390,10 +390,8 @@ struct SK_API SkIRect {
|
|||
struct SK_API SkRect {
|
||||
SkScalar fLeft, fTop, fRight, fBottom;
|
||||
|
||||
static SkRect SK_WARN_UNUSED_RESULT MakeEmpty() {
|
||||
SkRect r;
|
||||
r.setEmpty();
|
||||
return r;
|
||||
static constexpr SkRect SK_WARN_UNUSED_RESULT MakeEmpty() {
|
||||
return SkRect{0, 0, 0, 0};
|
||||
}
|
||||
|
||||
static SkRect SK_WARN_UNUSED_RESULT MakeLargest() {
|
||||
|
@ -420,10 +418,9 @@ struct SK_API SkRect {
|
|||
return r;
|
||||
}
|
||||
|
||||
static SkRect SK_WARN_UNUSED_RESULT MakeLTRB(SkScalar l, SkScalar t, SkScalar r, SkScalar b) {
|
||||
SkRect rect;
|
||||
rect.set(l, t, r, b);
|
||||
return rect;
|
||||
static constexpr SkRect SK_WARN_UNUSED_RESULT MakeLTRB(SkScalar l, SkScalar t, SkScalar r,
|
||||
SkScalar b) {
|
||||
return SkRect {l, t, r, b};
|
||||
}
|
||||
|
||||
static SkRect SK_WARN_UNUSED_RESULT MakeXYWH(SkScalar x, SkScalar y, SkScalar w, SkScalar h) {
|
||||
|
@ -442,6 +439,10 @@ struct SK_API SkRect {
|
|||
return r;
|
||||
}
|
||||
|
||||
static SkRect Make(const SkISize& size) {
|
||||
return MakeIWH(size.width(), size.height());
|
||||
}
|
||||
|
||||
static SkRect SK_WARN_UNUSED_RESULT Make(const SkIRect& irect) {
|
||||
SkRect r;
|
||||
r.set(SkIntToScalar(irect.fLeft),
|
||||
|
@ -506,7 +507,7 @@ struct SK_API SkRect {
|
|||
|
||||
/** Set this rectangle to the empty rectangle (0,0,0,0)
|
||||
*/
|
||||
void setEmpty() { memset(this, 0, sizeof(*this)); }
|
||||
void setEmpty() { *this = MakeEmpty(); }
|
||||
|
||||
void set(const SkIRect& src) {
|
||||
fLeft = SkIntToScalar(src.fLeft);
|
||||
|
|
|
@ -8,11 +8,12 @@
|
|||
#ifndef SkRefCnt_DEFINED
|
||||
#define SkRefCnt_DEFINED
|
||||
|
||||
#include "../private/SkAtomics.h"
|
||||
#include "../private/SkTLogic.h"
|
||||
#include "SkTypes.h"
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#define SK_SUPPORT_TRANSITION_TO_SP_INTERFACES
|
||||
|
@ -37,19 +38,28 @@ public:
|
|||
*/
|
||||
virtual ~SkRefCntBase() {
|
||||
#ifdef SK_DEBUG
|
||||
SkASSERTF(fRefCnt == 1, "fRefCnt was %d", fRefCnt);
|
||||
fRefCnt = 0; // illegal value, to catch us if we reuse after delete
|
||||
SkASSERTF(getRefCnt() == 1, "fRefCnt was %d", getRefCnt());
|
||||
// illegal value, to catch us if we reuse after delete
|
||||
fRefCnt.store(0, std::memory_order_relaxed);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Return the reference count. Use only for debugging. */
|
||||
int32_t getRefCnt() const { return fRefCnt; }
|
||||
int32_t getRefCnt() const {
|
||||
return fRefCnt.load(std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
void validate() const {
|
||||
SkASSERT(getRefCnt() > 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** May return true if the caller is the only owner.
|
||||
* Ensures that all previous owner's actions are complete.
|
||||
*/
|
||||
bool unique() const {
|
||||
if (1 == sk_atomic_load(&fRefCnt, sk_memory_order_acquire)) {
|
||||
if (1 == fRefCnt.load(std::memory_order_acquire)) {
|
||||
// The acquire barrier is only really needed if we return true. It
|
||||
// prevents code conditioned on the result of unique() from running
|
||||
// until previous owners are all totally done calling unref().
|
||||
|
@ -66,11 +76,12 @@ public:
|
|||
// go to zero, but not below, prior to reusing the object. This breaks
|
||||
// the use of unique() on such objects and as such should be removed
|
||||
// once the Android code is fixed.
|
||||
SkASSERT(fRefCnt >= 0);
|
||||
SkASSERT(getRefCnt() >= 0);
|
||||
#else
|
||||
SkASSERT(fRefCnt > 0);
|
||||
SkASSERT(getRefCnt() > 0);
|
||||
#endif
|
||||
(void)sk_atomic_fetch_add(&fRefCnt, +1, sk_memory_order_relaxed); // No barrier required.
|
||||
// No barrier required.
|
||||
(void)fRefCnt.fetch_add(+1, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
/** Decrement the reference count. If the reference count is 1 before the
|
||||
|
@ -78,33 +89,24 @@ public:
|
|||
the object needs to have been allocated via new, and not on the stack.
|
||||
*/
|
||||
void unref() const {
|
||||
SkASSERT(fRefCnt > 0);
|
||||
SkASSERT(getRefCnt() > 0);
|
||||
// A release here acts in place of all releases we "should" have been doing in ref().
|
||||
if (1 == sk_atomic_fetch_add(&fRefCnt, -1, sk_memory_order_acq_rel)) {
|
||||
if (1 == fRefCnt.fetch_add(-1, std::memory_order_acq_rel)) {
|
||||
// Like unique(), the acquire is only needed on success, to make sure
|
||||
// code in internal_dispose() doesn't happen before the decrement.
|
||||
this->internal_dispose();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
void validate() const {
|
||||
SkASSERT(fRefCnt > 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Allow subclasses to call this if they've overridden internal_dispose
|
||||
* so they can reset fRefCnt before the destructor is called. Should only
|
||||
* be called right before calling through to inherited internal_dispose()
|
||||
* or before calling the destructor.
|
||||
* so they can reset fRefCnt before the destructor is called or if they
|
||||
* choose not to call the destructor (e.g. using a free list).
|
||||
*/
|
||||
void internal_dispose_restore_refcnt_to_1() const {
|
||||
#ifdef SK_DEBUG
|
||||
SkASSERT(0 == fRefCnt);
|
||||
fRefCnt = 1;
|
||||
#endif
|
||||
SkASSERT(0 == getRefCnt());
|
||||
fRefCnt.store(1, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -120,7 +122,7 @@ private:
|
|||
// and conditionally call SkRefCnt::internal_dispose().
|
||||
friend class SkWeakRefCnt;
|
||||
|
||||
mutable int32_t fRefCnt;
|
||||
mutable std::atomic<int32_t> fRefCnt;
|
||||
|
||||
typedef SkNoncopyable INHERITED;
|
||||
};
|
||||
|
@ -130,7 +132,13 @@ private:
|
|||
// This SkRefCnt should normally derive from SkRefCntBase.
|
||||
#include SK_REF_CNT_MIXIN_INCLUDE
|
||||
#else
|
||||
class SK_API SkRefCnt : public SkRefCntBase { };
|
||||
class SK_API SkRefCnt : public SkRefCntBase {
|
||||
// "#include SK_REF_CNT_MIXIN_INCLUDE" doesn't work with this build system.
|
||||
#if defined(GOOGLE3)
|
||||
public:
|
||||
void deref() const { this->unref(); }
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -213,25 +221,29 @@ template <typename Derived>
|
|||
class SkNVRefCnt : SkNoncopyable {
|
||||
public:
|
||||
SkNVRefCnt() : fRefCnt(1) {}
|
||||
~SkNVRefCnt() { SkASSERTF(1 == fRefCnt, "NVRefCnt was %d", fRefCnt); }
|
||||
~SkNVRefCnt() { SkASSERTF(1 == getRefCnt(), "NVRefCnt was %d", getRefCnt()); }
|
||||
|
||||
// Implementation is pretty much the same as SkRefCntBase. All required barriers are the same:
|
||||
// - unique() needs acquire when it returns true, and no barrier if it returns false;
|
||||
// - ref() doesn't need any barrier;
|
||||
// - unref() needs a release barrier, and an acquire if it's going to call delete.
|
||||
|
||||
bool unique() const { return 1 == sk_atomic_load(&fRefCnt, sk_memory_order_acquire); }
|
||||
void ref() const { (void)sk_atomic_fetch_add(&fRefCnt, +1, sk_memory_order_relaxed); }
|
||||
bool unique() const { return 1 == fRefCnt.load(std::memory_order_acquire); }
|
||||
void ref() const { (void)fRefCnt.fetch_add(+1, std::memory_order_relaxed); }
|
||||
void unref() const {
|
||||
if (1 == sk_atomic_fetch_add(&fRefCnt, -1, sk_memory_order_acq_rel)) {
|
||||
SkDEBUGCODE(fRefCnt = 1;) // restore the 1 for our destructor's assert
|
||||
if (1 == fRefCnt.fetch_add(-1, std::memory_order_acq_rel)) {
|
||||
// restore the 1 for our destructor's assert
|
||||
SkDEBUGCODE(fRefCnt.store(1, std::memory_order_relaxed));
|
||||
delete (const Derived*)this;
|
||||
}
|
||||
}
|
||||
void deref() const { this->unref(); }
|
||||
|
||||
private:
|
||||
mutable int32_t fRefCnt;
|
||||
mutable std::atomic<int32_t> fRefCnt;
|
||||
int32_t getRefCnt() const {
|
||||
return fRefCnt.load(std::memory_order_relaxed);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -249,15 +261,15 @@ template <typename T> class sk_sp {
|
|||
public:
|
||||
using element_type = T;
|
||||
|
||||
sk_sp() : fPtr(nullptr) {}
|
||||
sk_sp(std::nullptr_t) : fPtr(nullptr) {}
|
||||
constexpr sk_sp() : fPtr(nullptr) {}
|
||||
constexpr sk_sp(std::nullptr_t) : fPtr(nullptr) {}
|
||||
|
||||
/**
|
||||
* Shares the underlying object by calling ref(), so that both the argument and the newly
|
||||
* created sk_sp both have a reference to it.
|
||||
*/
|
||||
sk_sp(const sk_sp<T>& that) : fPtr(SkSafeRef(that.get())) {}
|
||||
template <typename U, typename = skstd::enable_if_t<skstd::is_convertible<U*, T*>::value>>
|
||||
template <typename U, typename = skstd::enable_if_t<std::is_convertible<U*, T*>::value>>
|
||||
sk_sp(const sk_sp<U>& that) : fPtr(SkSafeRef(that.get())) {}
|
||||
|
||||
/**
|
||||
|
@ -266,7 +278,7 @@ public:
|
|||
* No call to ref() or unref() will be made.
|
||||
*/
|
||||
sk_sp(sk_sp<T>&& that) : fPtr(that.release()) {}
|
||||
template <typename U, typename = skstd::enable_if_t<skstd::is_convertible<U*, T*>::value>>
|
||||
template <typename U, typename = skstd::enable_if_t<std::is_convertible<U*, T*>::value>>
|
||||
sk_sp(sk_sp<U>&& that) : fPtr(that.release()) {}
|
||||
|
||||
/**
|
||||
|
@ -294,7 +306,7 @@ public:
|
|||
this->reset(SkSafeRef(that.get()));
|
||||
return *this;
|
||||
}
|
||||
template <typename U, typename = skstd::enable_if_t<skstd::is_convertible<U*, T*>::value>>
|
||||
template <typename U, typename = skstd::enable_if_t<std::is_convertible<U*, T*>::value>>
|
||||
sk_sp<T>& operator=(const sk_sp<U>& that) {
|
||||
this->reset(SkSafeRef(that.get()));
|
||||
return *this;
|
||||
|
@ -309,7 +321,7 @@ public:
|
|||
this->reset(that.release());
|
||||
return *this;
|
||||
}
|
||||
template <typename U, typename = skstd::enable_if_t<skstd::is_convertible<U*, T*>::value>>
|
||||
template <typename U, typename = skstd::enable_if_t<std::is_convertible<U*, T*>::value>>
|
||||
sk_sp<T>& operator=(sk_sp<U>&& that) {
|
||||
this->reset(that.release());
|
||||
return *this;
|
||||
|
@ -391,7 +403,7 @@ template <typename T, typename U> inline bool operator<(const sk_sp<T>& a, const
|
|||
// Provide defined total order on sk_sp.
|
||||
// http://wg21.cmeerw.net/lwg/issue1297
|
||||
// http://wg21.cmeerw.net/lwg/issue1401 .
|
||||
return std::less<void*>()((void*)a.get(), (void*)b.get());
|
||||
return std::less<skstd::common_type_t<T*, U*>>()(a.get(), b.get());
|
||||
}
|
||||
template <typename T> inline bool operator<(const sk_sp<T>& a, std::nullptr_t) {
|
||||
return std::less<T*>()(a.get(), nullptr);
|
||||
|
@ -432,7 +444,7 @@ template <typename T> inline bool operator>=(std::nullptr_t, const sk_sp<T>& b)
|
|||
|
||||
template <typename T, typename... Args>
|
||||
sk_sp<T> sk_make_sp(Args&&... args) {
|
||||
return sk_sp<T>(new T(std__forward<Args>(args)...));
|
||||
return sk_sp<T>(new T(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
#ifdef SK_SUPPORT_TRANSITION_TO_SP_INTERFACES
|
||||
|
|
|
@ -255,7 +255,15 @@ public:
|
|||
* specified rectangle: this = (this op rect).
|
||||
* Return true if the resulting region is non-empty.
|
||||
*/
|
||||
bool op(const SkIRect& rect, Op op) { return this->op(*this, rect, op); }
|
||||
bool op(const SkIRect& rect, Op op) {
|
||||
if (this->isRect() && kIntersect_Op == op) {
|
||||
if (!fBounds.intersect(rect)) {
|
||||
return this->setEmpty();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return this->op(*this, rect, op);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this region to the result of applying the Op to this region and the
|
||||
|
|
|
@ -101,6 +101,7 @@ typedef double SkScalar;
|
|||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define SkIntToScalar(x) static_cast<SkScalar>(x)
|
||||
#define SkIntToFloat(x) static_cast<float>(x)
|
||||
#define SkScalarTruncToInt(x) static_cast<int>(x)
|
||||
|
||||
#define SkScalarToFloat(x) static_cast<float>(x)
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
#include "../gpu/GrColor.h"
|
||||
|
||||
class SkColorFilter;
|
||||
class SkColorSpace;
|
||||
class SkImage;
|
||||
class SkPath;
|
||||
class SkPicture;
|
||||
class SkXfermode;
|
||||
|
@ -227,6 +229,7 @@ public:
|
|||
*/
|
||||
size_t contextSize(const ContextRec&) const;
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_SHADER_ISABITMAP
|
||||
/**
|
||||
* Returns true if this shader is just a bitmap, and if not null, returns the bitmap,
|
||||
* localMatrix, and tilemodes. If this is not a bitmap, returns false and ignores the
|
||||
|
@ -239,6 +242,19 @@ public:
|
|||
bool isABitmap() const {
|
||||
return this->isABitmap(nullptr, nullptr, nullptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Iff this shader is backed by a single SkImage, return its ptr (the caller must ref this
|
||||
* if they want to keep it longer than the lifetime of the shader). If not, return nullptr.
|
||||
*/
|
||||
SkImage* isAImage(SkMatrix* localMatrix, TileMode xy[2]) const {
|
||||
return this->onIsAImage(localMatrix, xy);
|
||||
}
|
||||
|
||||
bool isAImage() const {
|
||||
return this->isAImage(nullptr, nullptr) != nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the shader subclass can be represented as a gradient, asAGradient
|
||||
|
@ -309,6 +325,28 @@ public:
|
|||
|
||||
virtual bool asACompose(ComposeRec*) const { return false; }
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
struct AsFPArgs {
|
||||
AsFPArgs(GrContext* context,
|
||||
const SkMatrix* viewMatrix,
|
||||
const SkMatrix* localMatrix,
|
||||
SkFilterQuality filterQuality,
|
||||
SkColorSpace* dstColorSpace,
|
||||
SkSourceGammaTreatment gammaTreatment)
|
||||
: fContext(context)
|
||||
, fViewMatrix(viewMatrix)
|
||||
, fLocalMatrix(localMatrix)
|
||||
, fFilterQuality(filterQuality)
|
||||
, fDstColorSpace(dstColorSpace)
|
||||
, fGammaTreatment(gammaTreatment) {}
|
||||
|
||||
GrContext* fContext;
|
||||
const SkMatrix* fViewMatrix;
|
||||
const SkMatrix* fLocalMatrix;
|
||||
SkFilterQuality fFilterQuality;
|
||||
SkColorSpace* fDstColorSpace;
|
||||
SkSourceGammaTreatment fGammaTreatment;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a GrFragmentProcessor that implements the shader for the GPU backend. NULL is
|
||||
|
@ -323,10 +361,8 @@ public:
|
|||
* The returned GrFragmentProcessor should expect an unpremultiplied input color and
|
||||
* produce a premultiplied output.
|
||||
*/
|
||||
virtual const GrFragmentProcessor* asFragmentProcessor(GrContext*,
|
||||
const SkMatrix& viewMatrix,
|
||||
const SkMatrix* localMatrix,
|
||||
SkFilterQuality) const;
|
||||
virtual sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* If the shader can represent its "average" luminance in a single color, return true and
|
||||
|
@ -375,6 +411,14 @@ public:
|
|||
*/
|
||||
static sk_sp<SkShader> MakeColorShader(SkColor);
|
||||
|
||||
/**
|
||||
* Create a shader that draws the specified color (in the specified colorspace).
|
||||
*
|
||||
* This works around the limitation that SkPaint::setColor() only takes byte values, and does
|
||||
* not support specific colorspaces.
|
||||
*/
|
||||
static sk_sp<SkShader> MakeColorShader(const SkColor4f&, sk_sp<SkColorSpace>);
|
||||
|
||||
static sk_sp<SkShader> MakeComposeShader(sk_sp<SkShader> dst, sk_sp<SkShader> src,
|
||||
SkXfermode::Mode);
|
||||
|
||||
|
@ -457,6 +501,7 @@ public:
|
|||
|
||||
SK_TO_STRING_VIRT()
|
||||
SK_DEFINE_FLATTENABLE_TYPE(SkShader)
|
||||
SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
|
||||
|
||||
protected:
|
||||
void flatten(SkWriteBuffer&) const override;
|
||||
|
@ -479,9 +524,15 @@ protected:
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_SHADER_ISABITMAP
|
||||
virtual bool onIsABitmap(SkBitmap*, SkMatrix*, TileMode[2]) const {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual SkImage* onIsAImage(SkMatrix*, TileMode[2]) const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
// This is essentially const, but not officially so it can be modified in
|
||||
|
@ -490,7 +541,7 @@ private:
|
|||
|
||||
// So the SkLocalMatrixShader can whack fLocalMatrix in its SkReadBuffer constructor.
|
||||
friend class SkLocalMatrixShader;
|
||||
friend class SkBitmapProcShader; // for computeTotalInverse()
|
||||
friend class SkBitmapProcLegacyShader; // for computeTotalInverse()
|
||||
|
||||
typedef SkFlattenable INHERITED;
|
||||
};
|
||||
|
|
|
@ -40,11 +40,9 @@ public:
|
|||
virtual ~SkStream() {}
|
||||
|
||||
/**
|
||||
* Attempts to open the specified file, and return a stream to it (using
|
||||
* mmap if available). On success, the caller is responsible for deleting.
|
||||
* On failure, returns NULL.
|
||||
* Attempts to open the specified file as a stream, returns nullptr on failure.
|
||||
*/
|
||||
static SkStreamAsset* NewFromFile(const char path[]);
|
||||
static std::unique_ptr<SkStreamAsset> MakeFromFile(const char path[]);
|
||||
|
||||
/** Reads or skips size number of bytes.
|
||||
* If buffer == NULL, skip size bytes, return how many were skipped.
|
||||
|
@ -200,7 +198,10 @@ public:
|
|||
bool write16(U16CPU);
|
||||
bool write32(uint32_t);
|
||||
|
||||
bool writeText(const char text[]);
|
||||
bool writeText(const char text[]) {
|
||||
SkASSERT(text);
|
||||
return this->write(text, strlen(text));
|
||||
}
|
||||
bool writeDecAsText(int32_t);
|
||||
bool writeBigDecAsText(int64_t, int minDigits = 0);
|
||||
bool writeHexAsText(uint32_t, int minDigits = 0);
|
||||
|
@ -288,11 +289,13 @@ public:
|
|||
/** If copyData is true, the stream makes a private copy of the data. */
|
||||
SkMemoryStream(const void* data, size_t length, bool copyData = false);
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_STREAM_DATA
|
||||
/** Use the specified data as the memory for this stream.
|
||||
* The stream will call ref() on the data (assuming it is not NULL).
|
||||
* DEPRECATED
|
||||
*/
|
||||
SkMemoryStream(SkData*);
|
||||
#endif
|
||||
|
||||
/** Creates the stream to read from the specified data */
|
||||
SkMemoryStream(sk_sp<SkData>);
|
||||
|
@ -309,17 +312,24 @@ public:
|
|||
*/
|
||||
void setMemoryOwned(const void* data, size_t length);
|
||||
|
||||
sk_sp<SkData> asData() const { return fData; }
|
||||
void setData(sk_sp<SkData>);
|
||||
#ifdef SK_SUPPORT_LEGACY_STREAM_DATA
|
||||
/** Return the stream's data in a SkData.
|
||||
* The caller must call unref() when it is finished using the data.
|
||||
*/
|
||||
SkData* copyToData() const;
|
||||
SkData* copyToData() const { return asData().release(); }
|
||||
|
||||
/**
|
||||
* Use the specified data as the memory for this stream.
|
||||
* The stream will call ref() on the data (assuming it is not NULL).
|
||||
* The function returns the data parameter as a convenience.
|
||||
*/
|
||||
SkData* setData(SkData*);
|
||||
SkData* setData(SkData* data) {
|
||||
this->setData(sk_ref_sp(data));
|
||||
return data;
|
||||
}
|
||||
#endif
|
||||
|
||||
void skipToAlign4();
|
||||
const void* getAtPos();
|
||||
|
@ -401,11 +411,18 @@ public:
|
|||
void copyTo(void* dst) const;
|
||||
void writeToStream(SkWStream* dst) const;
|
||||
|
||||
sk_sp<SkData> snapshotAsData() const;
|
||||
// Return the contents as SkData, and then reset the stream.
|
||||
sk_sp<SkData> detachAsData();
|
||||
#ifdef SK_SUPPORT_LEGACY_STREAM_DATA
|
||||
/**
|
||||
* Return a copy of the data written so far. This call is responsible for
|
||||
* calling unref() when they are finished with the data.
|
||||
*/
|
||||
SkData* copyToData() const;
|
||||
SkData* copyToData() const {
|
||||
return snapshotAsData().release();
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Reset, returning a reader stream with the current content. */
|
||||
SkStreamAsset* detachAsStream();
|
||||
|
|
|
@ -98,6 +98,22 @@ public:
|
|||
*/
|
||||
void applyToPaint(SkPaint* paint) const;
|
||||
|
||||
/**
|
||||
* Gives a conservative value for the outset that should applied to a
|
||||
* geometries bounds to account for any inflation due to applying this
|
||||
* strokeRec to the geometry.
|
||||
*/
|
||||
SkScalar getInflationRadius() const;
|
||||
|
||||
/**
|
||||
* Equivalent to:
|
||||
* SkStrokeRec rec(paint, style);
|
||||
* rec.getInflationRadius();
|
||||
* This does not account for other effects on the paint (i.e. path
|
||||
* effect).
|
||||
*/
|
||||
static SkScalar GetInflationRadius(const SkPaint&, SkPaint::Style);
|
||||
|
||||
/**
|
||||
* Compare if two SkStrokeRecs have an equal effect on a path.
|
||||
* Equal SkStrokeRecs produce equal paths. Equality of produced
|
||||
|
|
|
@ -36,6 +36,8 @@ public:
|
|||
*
|
||||
* If the requested surface cannot be created, or the request is not a
|
||||
* supported configuration, NULL will be returned.
|
||||
*
|
||||
* Callers are responsible for initialiazing the surface pixels.
|
||||
*/
|
||||
static sk_sp<SkSurface> MakeRasterDirect(const SkImageInfo&, void* pixels, size_t rowBytes,
|
||||
const SkSurfaceProps* = nullptr);
|
||||
|
@ -49,11 +51,15 @@ public:
|
|||
void* context, const SkSurfaceProps* = nullptr);
|
||||
|
||||
/**
|
||||
* Return a new surface, with the memory for the pixels automatically allocated, but respecting
|
||||
* Return a new surface, with the memory for the pixels automatically allocated but respecting
|
||||
* the specified rowBytes. If rowBytes==0, then a default value will be chosen. If a non-zero
|
||||
* rowBytes is specified, then any images snapped off of this surface (via newImageSnapshot())
|
||||
* rowBytes is specified, then any images snapped off of this surface (via makeImageSnapshot())
|
||||
* are guaranteed to have the same rowBytes.
|
||||
*
|
||||
* If the requested alpha type is not opaque, then the surface's pixel memory will be
|
||||
* zero-initialized. If it is opaque, then it will be left uninitialized, and the caller is
|
||||
* responsible for initially clearing the surface.
|
||||
*
|
||||
* If the requested surface cannot be created, or the request is not a
|
||||
* supported configuration, NULL will be returned.
|
||||
*/
|
||||
|
@ -62,7 +68,10 @@ public:
|
|||
/**
|
||||
* Allocate a new surface, automatically computing the rowBytes.
|
||||
*/
|
||||
static sk_sp<SkSurface> MakeRaster(const SkImageInfo&, const SkSurfaceProps* = nullptr);
|
||||
static sk_sp<SkSurface> MakeRaster(const SkImageInfo& info,
|
||||
const SkSurfaceProps* props = nullptr) {
|
||||
return MakeRaster(info, 0, props);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper version of NewRaster. It creates a SkImageInfo with the
|
||||
|
@ -74,12 +83,6 @@ public:
|
|||
return MakeRaster(SkImageInfo::MakeN32Premul(width, height), props);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new surface using the specified render target.
|
||||
*/
|
||||
static sk_sp<SkSurface> MakeRenderTargetDirect(GrRenderTarget*,
|
||||
const SkSurfaceProps* = nullptr);
|
||||
|
||||
/**
|
||||
* Used to wrap a pre-existing backend 3D API texture as a SkSurface. The kRenderTarget flag
|
||||
* must be set on GrBackendTextureDesc for this to succeed. Skia will not assume ownership
|
||||
|
@ -87,7 +90,7 @@ public:
|
|||
* SkSurface.
|
||||
*/
|
||||
static sk_sp<SkSurface> MakeFromBackendTexture(GrContext*, const GrBackendTextureDesc&,
|
||||
const SkSurfaceProps*);
|
||||
sk_sp<SkColorSpace>, const SkSurfaceProps*);
|
||||
|
||||
/**
|
||||
* Used to wrap a pre-existing 3D API rendering target as a SkSurface. Skia will not assume
|
||||
|
@ -96,6 +99,7 @@ public:
|
|||
*/
|
||||
static sk_sp<SkSurface> MakeFromBackendRenderTarget(GrContext*,
|
||||
const GrBackendRenderTargetDesc&,
|
||||
sk_sp<SkColorSpace>,
|
||||
const SkSurfaceProps*);
|
||||
|
||||
/**
|
||||
|
@ -107,21 +111,46 @@ public:
|
|||
* SkSurface.
|
||||
*/
|
||||
static sk_sp<SkSurface> MakeFromBackendTextureAsRenderTarget(
|
||||
GrContext*, const GrBackendTextureDesc&, const SkSurfaceProps*);
|
||||
GrContext*, const GrBackendTextureDesc&, sk_sp<SkColorSpace>, const SkSurfaceProps*);
|
||||
|
||||
/**
|
||||
* Legacy versions of the above factories, without color space support. These create "legacy"
|
||||
* surfaces that operate without gamma correction or color management.
|
||||
*/
|
||||
static sk_sp<SkSurface> MakeFromBackendTexture(GrContext* ctx, const GrBackendTextureDesc& desc,
|
||||
const SkSurfaceProps* props) {
|
||||
return MakeFromBackendTexture(ctx, desc, nullptr, props);
|
||||
}
|
||||
|
||||
static sk_sp<SkSurface> MakeFromBackendRenderTarget(GrContext* ctx,
|
||||
const GrBackendRenderTargetDesc& desc,
|
||||
const SkSurfaceProps* props) {
|
||||
return MakeFromBackendRenderTarget(ctx, desc, nullptr, props);
|
||||
}
|
||||
|
||||
static sk_sp<SkSurface> MakeFromBackendTextureAsRenderTarget(
|
||||
GrContext* ctx, const GrBackendTextureDesc& desc, const SkSurfaceProps* props) {
|
||||
return MakeFromBackendTextureAsRenderTarget(ctx, desc, nullptr, props);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a new surface whose contents will be drawn to an offscreen
|
||||
* render target, allocated by the surface.
|
||||
*
|
||||
* The GrTextureStorageAllocator will be reused if SkImage snapshots create
|
||||
* additional textures.
|
||||
*/
|
||||
static sk_sp<SkSurface> MakeRenderTarget(
|
||||
GrContext*, SkBudgeted, const SkImageInfo&, int sampleCount, const SkSurfaceProps*,
|
||||
GrTextureStorageAllocator = GrTextureStorageAllocator());
|
||||
static sk_sp<SkSurface> MakeRenderTarget(GrContext*, SkBudgeted, const SkImageInfo&,
|
||||
int sampleCount, GrSurfaceOrigin,
|
||||
const SkSurfaceProps*);
|
||||
|
||||
static sk_sp<SkSurface> MakeRenderTarget(GrContext* context, SkBudgeted budgeted,
|
||||
const SkImageInfo& info, int sampleCount,
|
||||
const SkSurfaceProps* props) {
|
||||
return MakeRenderTarget(context, budgeted, info, sampleCount,
|
||||
kBottomLeft_GrSurfaceOrigin, props);
|
||||
}
|
||||
|
||||
static sk_sp<SkSurface> MakeRenderTarget(GrContext* gr, SkBudgeted b, const SkImageInfo& info) {
|
||||
return MakeRenderTarget(gr, b, info, 0, nullptr);
|
||||
return MakeRenderTarget(gr, b, info, 0, kBottomLeft_GrSurfaceOrigin, nullptr);
|
||||
}
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_NEW_SURFACE_API
|
||||
|
@ -147,12 +176,6 @@ public:
|
|||
const SkSurfaceProps* props = NULL) {
|
||||
return NewRaster(SkImageInfo::MakeN32Premul(width, height), props);
|
||||
}
|
||||
static SkSurface* NewRenderTargetDirect(GrRenderTarget* rt, const SkSurfaceProps* props) {
|
||||
return MakeRenderTargetDirect(rt, props).release();
|
||||
}
|
||||
static SkSurface* NewRenderTargetDirect(GrRenderTarget* target) {
|
||||
return NewRenderTargetDirect(target, NULL);
|
||||
}
|
||||
static SkSurface* NewFromBackendTexture(GrContext* ctx, const GrBackendTextureDesc& desc,
|
||||
const SkSurfaceProps* props) {
|
||||
return MakeFromBackendTexture(ctx, desc, props).release();
|
||||
|
@ -172,9 +195,8 @@ public:
|
|||
return MakeFromBackendTextureAsRenderTarget(ctx, desc, props).release();
|
||||
}
|
||||
static SkSurface* NewRenderTarget(GrContext* ctx, SkBudgeted b, const SkImageInfo& info,
|
||||
int sampleCount, const SkSurfaceProps* props = NULL,
|
||||
GrTextureStorageAllocator a = GrTextureStorageAllocator()) {
|
||||
return MakeRenderTarget(ctx, b, info, sampleCount, props, a).release();
|
||||
int sampleCount, const SkSurfaceProps* props = NULL) {
|
||||
return MakeRenderTarget(ctx, b, info, sampleCount, props).release();
|
||||
}
|
||||
static SkSurface* NewRenderTarget(GrContext* gr, SkBudgeted b, const SkImageInfo& info) {
|
||||
return NewRenderTarget(gr, b, info, 0);
|
||||
|
|
|
@ -51,20 +51,7 @@ static inline bool SkPixelGeometryIsV(SkPixelGeometry geo) {
|
|||
class SK_API SkSurfaceProps {
|
||||
public:
|
||||
enum Flags {
|
||||
kDisallowAntiAlias_Flag = 1 << 0,
|
||||
kDisallowDither_Flag = 1 << 1,
|
||||
kUseDeviceIndependentFonts_Flag = 1 << 2,
|
||||
|
||||
/**
|
||||
* This flag causes sRGB inputs to the color pipeline (images and other sRGB-tagged
|
||||
* colors) to be gamma-corrected (converted to linear) before use. Without this flag,
|
||||
* texture scaling and filtering is not gamma correct, preserving the behavior of Skia
|
||||
* up through 2015.
|
||||
*
|
||||
* It is recommended to enable this flag when rendering to an sRGB or floating point
|
||||
* surface.
|
||||
*/
|
||||
kAllowSRGBInputs_Flag = 1 << 3,
|
||||
kUseDeviceIndependentFonts_Flag = 1 << 0,
|
||||
};
|
||||
/** Deprecated alias used by Chromium. Will be removed. */
|
||||
static const Flags kUseDistanceFieldFonts_Flag = kUseDeviceIndependentFonts_Flag;
|
||||
|
@ -81,12 +68,9 @@ public:
|
|||
uint32_t flags() const { return fFlags; }
|
||||
SkPixelGeometry pixelGeometry() const { return fPixelGeometry; }
|
||||
|
||||
bool isDisallowAA() const { return SkToBool(fFlags & kDisallowAntiAlias_Flag); }
|
||||
bool isDisallowDither() const { return SkToBool(fFlags & kDisallowDither_Flag); }
|
||||
bool isUseDeviceIndependentFonts() const {
|
||||
return SkToBool(fFlags & kUseDeviceIndependentFonts_Flag);
|
||||
}
|
||||
bool allowSRGBInputs() const { return SkToBool(fFlags & kAllowSRGBInputs_Flag); }
|
||||
|
||||
private:
|
||||
SkSurfaceProps();
|
||||
|
|
|
@ -19,21 +19,12 @@
|
|||
*/
|
||||
template <typename T> class SkTLazy {
|
||||
public:
|
||||
SkTLazy() : fPtr(NULL) {}
|
||||
SkTLazy() : fPtr(nullptr) {}
|
||||
|
||||
explicit SkTLazy(const T* src) : fPtr(NULL) {
|
||||
if (src) {
|
||||
fPtr = new (fStorage.get()) T(*src);
|
||||
}
|
||||
}
|
||||
explicit SkTLazy(const T* src)
|
||||
: fPtr(src ? new (fStorage.get()) T(*src) : nullptr) {}
|
||||
|
||||
SkTLazy(const SkTLazy<T>& src) : fPtr(NULL) {
|
||||
if (src.isValid()) {
|
||||
fPtr = new (fStorage.get()) T(*src.get());
|
||||
} else {
|
||||
fPtr = NULL;
|
||||
}
|
||||
}
|
||||
SkTLazy(const SkTLazy& src) : fPtr(nullptr) { *this = src; }
|
||||
|
||||
~SkTLazy() {
|
||||
if (this->isValid()) {
|
||||
|
@ -41,6 +32,15 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
SkTLazy& operator=(const SkTLazy& src) {
|
||||
if (src.isValid()) {
|
||||
this->set(*src.get());
|
||||
} else {
|
||||
this->reset();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a pointer to an instance of the class initialized with 'args'.
|
||||
* If a previous instance had been initialized (either from init() or
|
||||
|
@ -51,7 +51,7 @@ public:
|
|||
if (this->isValid()) {
|
||||
fPtr->~T();
|
||||
}
|
||||
fPtr = new (SkTCast<T*>(fStorage.get())) T(std__forward<Args>(args)...);
|
||||
fPtr = new (SkTCast<T*>(fStorage.get())) T(std::forward<Args>(args)...);
|
||||
return fPtr;
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,7 @@ public:
|
|||
void reset() {
|
||||
if (this->isValid()) {
|
||||
fPtr->~T();
|
||||
fPtr = NULL;
|
||||
fPtr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,13 +94,13 @@ public:
|
|||
|
||||
/**
|
||||
* Like above but doesn't assert if object isn't initialized (in which case
|
||||
* NULL is returned).
|
||||
* nullptr is returned).
|
||||
*/
|
||||
T* getMaybeNull() const { return fPtr; }
|
||||
|
||||
private:
|
||||
T* fPtr; // NULL or fStorage
|
||||
SkAlignedSTStorage<1, T> fStorage;
|
||||
T* fPtr; // nullptr or fStorage
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -134,11 +134,11 @@ public:
|
|||
SkTCopyOnFirstWrite(const T* initial) : fObj(initial) {}
|
||||
|
||||
// Constructor for delayed initialization.
|
||||
SkTCopyOnFirstWrite() : fObj(NULL) {}
|
||||
SkTCopyOnFirstWrite() : fObj(nullptr) {}
|
||||
|
||||
// Should only be called once, and only if the default constructor was used.
|
||||
void init(const T& initial) {
|
||||
SkASSERT(NULL == fObj);
|
||||
SkASSERT(nullptr == fObj);
|
||||
SkASSERT(!fLazy.isValid());
|
||||
fObj = &initial;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "../private/SkTemplates.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkString.h"
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
class SkReadBuffer;
|
||||
|
@ -19,7 +20,7 @@ class SkWriteBuffer;
|
|||
|
||||
SkTextBlob combines multiple text runs into an immutable, ref-counted structure.
|
||||
*/
|
||||
class SK_API SkTextBlob : public SkRefCnt {
|
||||
class SK_API SkTextBlob final : public SkNVRefCnt<SkTextBlob> {
|
||||
public:
|
||||
/**
|
||||
* Returns a conservative blob bounding box.
|
||||
|
@ -43,20 +44,25 @@ public:
|
|||
* @return A new SkTextBlob representing the serialized data, or NULL if the buffer is
|
||||
* invalid.
|
||||
*/
|
||||
static const SkTextBlob* CreateFromBuffer(SkReadBuffer&);
|
||||
static sk_sp<SkTextBlob> MakeFromBuffer(SkReadBuffer&);
|
||||
|
||||
enum GlyphPositioning {
|
||||
static const SkTextBlob* CreateFromBuffer(SkReadBuffer& buffer) {
|
||||
return MakeFromBuffer(buffer).release();
|
||||
}
|
||||
|
||||
enum GlyphPositioning : uint8_t {
|
||||
kDefault_Positioning = 0, // Default glyph advances -- zero scalars per glyph.
|
||||
kHorizontal_Positioning = 1, // Horizontal positioning -- one scalar per glyph.
|
||||
kFull_Positioning = 2 // Point positioning -- two scalars per glyph.
|
||||
};
|
||||
|
||||
private:
|
||||
friend class SkNVRefCnt<SkTextBlob>;
|
||||
class RunRecord;
|
||||
|
||||
SkTextBlob(int runCount, const SkRect& bounds);
|
||||
|
||||
virtual ~SkTextBlob();
|
||||
~SkTextBlob();
|
||||
|
||||
// Memory for objects of this class is created with sk_malloc rather than operator new and must
|
||||
// be freed with sk_free.
|
||||
|
@ -98,16 +104,40 @@ public:
|
|||
* Returns an immutable SkTextBlob for the current runs/glyphs. The builder is reset and
|
||||
* can be reused.
|
||||
*/
|
||||
const SkTextBlob* build();
|
||||
sk_sp<SkTextBlob> make();
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_TEXTBLOB_BUILDER
|
||||
const SkTextBlob* build() {
|
||||
return this->make().release();
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Glyph and position buffers associated with a run.
|
||||
*
|
||||
* A run is a sequence of glyphs sharing the same font metrics and positioning mode.
|
||||
* A run is a sequence of glyphs sharing the same font metrics
|
||||
* and positioning mode.
|
||||
*
|
||||
* If textByteCount is 0, utf8text and clusters will be NULL (no
|
||||
* character information will be associated with the glyphs).
|
||||
*
|
||||
* utf8text will point to a buffer of size textByteCount bytes.
|
||||
*
|
||||
* clusters (if not NULL) will point to an array of size count.
|
||||
* For each glyph, give the byte-offset into the text for the
|
||||
* first byte in the first character in that glyph's cluster.
|
||||
* Each value in the array should be an integer less than
|
||||
* textByteCount. Values in the array should either be
|
||||
* monotonically increasing (left-to-right text) or monotonically
|
||||
* decreasing (right-to-left text). This definiton is conviently
|
||||
* the same as used by Harfbuzz's hb_glyph_info_t::cluster field,
|
||||
* except that Harfbuzz interleaves glyphs and clusters.
|
||||
*/
|
||||
struct RunBuffer {
|
||||
uint16_t* glyphs;
|
||||
SkGlyphID* glyphs;
|
||||
SkScalar* pos;
|
||||
char* utf8text;
|
||||
uint32_t* clusters;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -117,14 +147,27 @@ public:
|
|||
* @param font The font to be used for this run.
|
||||
* @param count Number of glyphs.
|
||||
* @param x,y Position within the blob.
|
||||
* @param textByteCount length of the original UTF-8 text that
|
||||
* corresponds to this sequence of glyphs. If 0,
|
||||
* text will not be included in the textblob.
|
||||
* @param lang Language code, currently unimplemented.
|
||||
* @param bounds Optional run bounding box. If known in advance (!= NULL), it will
|
||||
* be used when computing the blob bounds, to avoid re-measuring.
|
||||
*
|
||||
* @return A writable glyph buffer, valid until the next allocRun() or
|
||||
* build() call. The buffer is guaranteed to hold @count@ glyphs.
|
||||
*/
|
||||
const RunBuffer& allocRunText(const SkPaint& font,
|
||||
int count,
|
||||
SkScalar x,
|
||||
SkScalar y,
|
||||
int textByteCount,
|
||||
SkString lang,
|
||||
const SkRect* bounds = NULL);
|
||||
const RunBuffer& allocRun(const SkPaint& font, int count, SkScalar x, SkScalar y,
|
||||
const SkRect* bounds = NULL);
|
||||
const SkRect* bounds = NULL) {
|
||||
return this->allocRunText(font, count, x, y, 0, SkString(), bounds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates a new horizontally-positioned run and returns its writable glyph and position
|
||||
|
@ -133,14 +176,23 @@ public:
|
|||
* @param font The font to be used for this run.
|
||||
* @param count Number of glyphs.
|
||||
* @param y Vertical offset within the blob.
|
||||
* @param textByteCount length of the original UTF-8 text that
|
||||
* corresponds to this sequence of glyphs. If 0,
|
||||
* text will not be included in the textblob.
|
||||
* @param lang Language code, currently unimplemented.
|
||||
* @param bounds Optional run bounding box. If known in advance (!= NULL), it will
|
||||
* be used when computing the blob bounds, to avoid re-measuring.
|
||||
*
|
||||
* @return Writable glyph and position buffers, valid until the next allocRun()
|
||||
* or build() call. The buffers are guaranteed to hold @count@ elements.
|
||||
*/
|
||||
const RunBuffer& allocRunTextPosH(const SkPaint& font, int count, SkScalar y,
|
||||
int textByteCount, SkString lang,
|
||||
const SkRect* bounds = NULL);
|
||||
const RunBuffer& allocRunPosH(const SkPaint& font, int count, SkScalar y,
|
||||
const SkRect* bounds = NULL);
|
||||
const SkRect* bounds = NULL) {
|
||||
return this->allocRunTextPosH(font, count, y, 0, SkString(), bounds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates a new fully-positioned run and returns its writable glyph and position
|
||||
|
@ -148,6 +200,10 @@ public:
|
|||
*
|
||||
* @param font The font to be used for this run.
|
||||
* @param count Number of glyphs.
|
||||
* @param textByteCount length of the original UTF-8 text that
|
||||
* corresponds to this sequence of glyphs. If 0,
|
||||
* text will not be included in the textblob.
|
||||
* @param lang Language code, currently unimplemented.
|
||||
* @param bounds Optional run bounding box. If known in advance (!= NULL), it will
|
||||
* be used when computing the blob bounds, to avoid re-measuring.
|
||||
*
|
||||
|
@ -155,12 +211,18 @@ public:
|
|||
* or build() call. The glyph buffer and position buffer are
|
||||
* guaranteed to hold @count@ and 2 * @count@ elements, respectively.
|
||||
*/
|
||||
const RunBuffer& allocRunPos(const SkPaint& font, int count, const SkRect* bounds = NULL);
|
||||
const RunBuffer& allocRunTextPos(const SkPaint& font, int count,
|
||||
int textByteCount, SkString lang,
|
||||
const SkRect* bounds = NULL);
|
||||
const RunBuffer& allocRunPos(const SkPaint& font, int count,
|
||||
const SkRect* bounds = NULL) {
|
||||
return this->allocRunTextPos(font, count, 0, SkString(), bounds);
|
||||
}
|
||||
|
||||
private:
|
||||
void reserve(size_t size);
|
||||
void allocInternal(const SkPaint& font, SkTextBlob::GlyphPositioning positioning,
|
||||
int count, SkPoint offset, const SkRect* bounds);
|
||||
int count, int textBytes, SkPoint offset, const SkRect* bounds);
|
||||
bool mergeRun(const SkPaint& font, SkTextBlob::GlyphPositioning positioning,
|
||||
int count, SkPoint offset);
|
||||
void updateDeferredBounds();
|
||||
|
|
|
@ -17,7 +17,7 @@ class SkString;
|
|||
/** \class SkTime
|
||||
Platform-implemented utilities to return time of day, and millisecond counter.
|
||||
*/
|
||||
class SkTime {
|
||||
class SK_API SkTime {
|
||||
public:
|
||||
struct DateTime {
|
||||
int16_t fTimeZoneMinutes; // The number of minutes that GetDateTime()
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*
|
||||
* Copyright 2006 The Android Open Source Project
|
||||
*
|
||||
|
@ -6,11 +5,11 @@
|
|||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SkTypeface_DEFINED
|
||||
#define SkTypeface_DEFINED
|
||||
|
||||
#include "../private/SkOncePtr.h"
|
||||
#include "../private/SkBitmaskEnum.h"
|
||||
#include "../private/SkOnce.h"
|
||||
#include "../private/SkWeakRefCnt.h"
|
||||
#include "SkFontStyle.h"
|
||||
#include "SkRect.h"
|
||||
|
@ -21,6 +20,7 @@ class SkFontData;
|
|||
class SkFontDescriptor;
|
||||
class SkScalerContext;
|
||||
struct SkScalerContextRec;
|
||||
struct SkScalerContextEffects;
|
||||
class SkStream;
|
||||
class SkStreamAsset;
|
||||
class SkAdvancedTypefaceMetrics;
|
||||
|
@ -93,51 +93,66 @@ public:
|
|||
*/
|
||||
static bool Equal(const SkTypeface* facea, const SkTypeface* faceb);
|
||||
|
||||
/**
|
||||
* Returns a ref() to the default typeface. The caller must call unref()
|
||||
* when they are done referencing the object. Never returns NULL.
|
||||
*/
|
||||
static SkTypeface* RefDefault(Style style = SkTypeface::kNormal);
|
||||
/** Returns the default typeface, which is never nullptr. */
|
||||
static sk_sp<SkTypeface> MakeDefault(Style style = SkTypeface::kNormal);
|
||||
#ifdef SK_SUPPORT_LEGACY_TYPEFACE_PTR
|
||||
static SkTypeface* RefDefault(Style style = SkTypeface::kNormal) {
|
||||
return MakeDefault(style).release();
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Return a new reference to the typeface that most closely matches the
|
||||
requested familyName and style. Pass null as the familyName to return
|
||||
the default font for the requested style. Will never return null
|
||||
/** Creates a new reference to the typeface that most closely matches the
|
||||
requested familyName and fontStyle. This method allows extended font
|
||||
face specifiers as in the SkFontStyle type. Will never return null.
|
||||
|
||||
@param familyName May be NULL. The name of the font family.
|
||||
@param style The style (normal, bold, italic) of the typeface.
|
||||
@return reference to the closest-matching typeface. Call must call
|
||||
unref() when they are done.
|
||||
@param familyName May be NULL. The name of the font family.
|
||||
@param fontStyle The style of the typeface.
|
||||
@return reference to the closest-matching typeface. Call must call
|
||||
unref() when they are done.
|
||||
*/
|
||||
static SkTypeface* CreateFromName(const char familyName[], Style style);
|
||||
static sk_sp<SkTypeface> MakeFromName(const char familyName[], SkFontStyle fontStyle);
|
||||
|
||||
/** Return a new reference to the typeface that most closely matches the
|
||||
requested typeface and specified Style. Use this call if you want to
|
||||
pick a new style from the same family of the existing typeface.
|
||||
If family is NULL, this selects from the default font's family.
|
||||
#ifdef SK_SUPPORT_LEGACY_TYPEFACE_PTR
|
||||
static SkTypeface* CreateFromName(const char familyName[], Style style) {
|
||||
return MakeFromName(familyName, SkFontStyle::FromOldStyle(style)).release();
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Return the typeface that most closely matches the requested typeface and style.
|
||||
Use this to pick a new style from the same family of the existing typeface.
|
||||
If family is nullptr, this selects from the default font's family.
|
||||
|
||||
@param family May be NULL. The name of the existing type face.
|
||||
@param s The style (normal, bold, italic) of the type face.
|
||||
@return reference to the closest-matching typeface. Call must call
|
||||
unref() when they are done.
|
||||
@return the closest-matching typeface.
|
||||
*/
|
||||
static SkTypeface* CreateFromTypeface(const SkTypeface* family, Style s);
|
||||
static sk_sp<SkTypeface> MakeFromTypeface(SkTypeface* family, Style);
|
||||
|
||||
/** Return a new typeface given a file. If the file does not exist, or is
|
||||
not a valid font file, returns null.
|
||||
not a valid font file, returns nullptr.
|
||||
*/
|
||||
static SkTypeface* CreateFromFile(const char path[], int index = 0);
|
||||
static sk_sp<SkTypeface> MakeFromFile(const char path[], int index = 0);
|
||||
#ifdef SK_SUPPORT_LEGACY_TYPEFACE_PTR
|
||||
static SkTypeface* CreateFromFile(const char path[], int index = 0) {
|
||||
return MakeFromFile(path, index).release();
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Return a new typeface given a stream. If the stream is
|
||||
not a valid font file, returns null. Ownership of the stream is
|
||||
not a valid font file, returns nullptr. Ownership of the stream is
|
||||
transferred, so the caller must not reference it again.
|
||||
*/
|
||||
static SkTypeface* CreateFromStream(SkStreamAsset* stream, int index = 0);
|
||||
static sk_sp<SkTypeface> MakeFromStream(SkStreamAsset* stream, int index = 0);
|
||||
#ifdef SK_SUPPORT_LEGACY_TYPEFACE_PTR
|
||||
static SkTypeface* CreateFromStream(SkStreamAsset* stream, int index = 0) {
|
||||
return MakeFromStream(stream, index).release();
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Return a new typeface given font data and configuration. If the data
|
||||
is not valid font data, returns null. Ownership of the font data is
|
||||
transferred, so the caller must not reference it again.
|
||||
is not valid font data, returns nullptr.
|
||||
*/
|
||||
static SkTypeface* CreateFromFontData(SkFontData*);
|
||||
static sk_sp<SkTypeface> MakeFromFontData(std::unique_ptr<SkFontData>);
|
||||
|
||||
/** Write a unique signature to a stream, sufficient to reconstruct a
|
||||
typeface referencing the same font when Deserialize is called.
|
||||
|
@ -145,12 +160,11 @@ public:
|
|||
void serialize(SkWStream*) const;
|
||||
|
||||
/** Given the data previously written by serialize(), return a new instance
|
||||
to a typeface referring to the same font. If that font is not available,
|
||||
return null. If an instance is returned, the caller is responsible for
|
||||
calling unref() when they are done with it.
|
||||
of a typeface referring to the same font. If that font is not available,
|
||||
return nullptr.
|
||||
Does not affect ownership of SkStream.
|
||||
*/
|
||||
static SkTypeface* Deserialize(SkStream*);
|
||||
static sk_sp<SkTypeface> MakeDeserialize(SkStream*);
|
||||
|
||||
enum Encoding {
|
||||
kUTF8_Encoding,
|
||||
|
@ -174,7 +188,7 @@ public:
|
|||
* from the beginning of chars. This value is valid, even if the
|
||||
* glyphs parameter is NULL.
|
||||
*/
|
||||
int charsToGlyphs(const void* chars, Encoding encoding, uint16_t glyphs[],
|
||||
int charsToGlyphs(const void* chars, Encoding encoding, SkGlyphID glyphs[],
|
||||
int glyphCount) const;
|
||||
|
||||
/**
|
||||
|
@ -248,7 +262,7 @@ public:
|
|||
* array will be in an undefined state (possibly some values may have been
|
||||
* written, but none of them should be interpreted as valid values).
|
||||
*/
|
||||
bool getKerningPairAdjustments(const uint16_t glyphs[], int count,
|
||||
bool getKerningPairAdjustments(const SkGlyphID glyphs[], int count,
|
||||
int32_t adjustments[]) const;
|
||||
|
||||
struct LocalizedString {
|
||||
|
@ -285,17 +299,16 @@ public:
|
|||
SkStreamAsset* openStream(int* ttcIndex) const;
|
||||
|
||||
/**
|
||||
* Return the font data, or NULL on failure.
|
||||
* The caller is responsible for deleting the font data.
|
||||
* Return the font data, or nullptr on failure.
|
||||
*/
|
||||
SkFontData* createFontData() const;
|
||||
std::unique_ptr<SkFontData> makeFontData() const;
|
||||
|
||||
/**
|
||||
* Return a scalercontext for the given descriptor. If this fails, then
|
||||
* if allowFailure is true, this returns NULL, else it returns a
|
||||
* dummy scalercontext that will not crash, but will draw nothing.
|
||||
*/
|
||||
SkScalerContext* createScalerContext(const SkDescriptor*,
|
||||
SkScalerContext* createScalerContext(const SkScalerContextEffects&, const SkDescriptor*,
|
||||
bool allowFailure = false) const;
|
||||
|
||||
/**
|
||||
|
@ -324,25 +337,26 @@ protected:
|
|||
// The type of advance data wanted.
|
||||
enum PerGlyphInfo {
|
||||
kNo_PerGlyphInfo = 0x0, // Don't populate any per glyph info.
|
||||
kHAdvance_PerGlyphInfo = 0x1, // Populate horizontal advance data.
|
||||
kVAdvance_PerGlyphInfo = 0x2, // Populate vertical advance data.
|
||||
kGlyphNames_PerGlyphInfo = 0x4, // Populate glyph names (Type 1 only).
|
||||
kToUnicode_PerGlyphInfo = 0x8 // Populate ToUnicode table, ignored
|
||||
// for Type 1 fonts
|
||||
kGlyphNames_PerGlyphInfo = 0x1, // Populate glyph names (Type 1 only).
|
||||
kToUnicode_PerGlyphInfo = 0x2 // Populate ToUnicode table, ignored
|
||||
// for Type 1 fonts
|
||||
};
|
||||
|
||||
/** uniqueID must be unique and non-zero
|
||||
*/
|
||||
SkTypeface(const SkFontStyle& style, SkFontID uniqueID, bool isFixedPitch = false);
|
||||
SkTypeface(const SkFontStyle& style, bool isFixedPitch = false);
|
||||
virtual ~SkTypeface();
|
||||
|
||||
/** Sets the fixedPitch bit. If used, must be called in the constructor. */
|
||||
void setIsFixedPitch(bool isFixedPitch) { fIsFixedPitch = isFixedPitch; }
|
||||
/** Sets the font style. If used, must be called in the constructor. */
|
||||
void setFontStyle(SkFontStyle style) { fStyle = style; }
|
||||
|
||||
friend class SkScalerContext;
|
||||
static SkTypeface* GetDefaultTypeface(Style style = SkTypeface::kNormal);
|
||||
|
||||
virtual SkScalerContext* onCreateScalerContext(const SkDescriptor*) const = 0;
|
||||
virtual SkScalerContext* onCreateScalerContext(const SkScalerContextEffects&,
|
||||
const SkDescriptor*) const = 0;
|
||||
virtual void onFilterRec(SkScalerContextRec*) const = 0;
|
||||
virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics(
|
||||
PerGlyphInfo,
|
||||
|
@ -351,16 +365,16 @@ protected:
|
|||
|
||||
virtual SkStreamAsset* onOpenStream(int* ttcIndex) const = 0;
|
||||
// TODO: make pure virtual.
|
||||
virtual SkFontData* onCreateFontData() const;
|
||||
virtual std::unique_ptr<SkFontData> onMakeFontData() const;
|
||||
|
||||
virtual void onGetFontDescriptor(SkFontDescriptor*, bool* isLocal) const = 0;
|
||||
|
||||
virtual int onCharsToGlyphs(const void* chars, Encoding, uint16_t glyphs[],
|
||||
virtual int onCharsToGlyphs(const void* chars, Encoding, SkGlyphID glyphs[],
|
||||
int glyphCount) const = 0;
|
||||
virtual int onCountGlyphs() const = 0;
|
||||
|
||||
virtual int onGetUPEM() const = 0;
|
||||
virtual bool onGetKerningPairAdjustments(const uint16_t glyphs[], int count,
|
||||
virtual bool onGetKerningPairAdjustments(const SkGlyphID glyphs[], int count,
|
||||
int32_t adjustments[]) const;
|
||||
|
||||
/** Returns the family name of the typeface as known by its font manager.
|
||||
|
@ -381,7 +395,6 @@ private:
|
|||
friend class SkGTypeface;
|
||||
friend class SkRandomTypeface;
|
||||
friend class SkPDFFont;
|
||||
friend class SkPDFCIDFont;
|
||||
friend class GrPathRendering;
|
||||
friend class GrGLPathRendering;
|
||||
|
||||
|
@ -401,12 +414,10 @@ private:
|
|||
uint32_t glyphIDsCount = 0) const;
|
||||
|
||||
private:
|
||||
static SkTypeface* CreateDefault(int style); // SkLazyPtr requires an int, not a Style.
|
||||
static void DeleteDefault(SkTypeface*);
|
||||
|
||||
SkOncePtr<SkRect> fLazyBounds;
|
||||
SkFontID fUniqueID;
|
||||
SkFontStyle fStyle;
|
||||
mutable SkRect fBounds;
|
||||
mutable SkOnce fBoundsOnce;
|
||||
bool fIsFixedPitch;
|
||||
|
||||
friend class SkPaint;
|
||||
|
@ -415,4 +426,8 @@ private:
|
|||
typedef SkWeakRefCnt INHERITED;
|
||||
};
|
||||
|
||||
namespace skstd {
|
||||
template <> struct is_bitmask_enum<SkTypeface::PerGlyphInfo> : std::true_type {};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -17,7 +17,11 @@
|
|||
// before #including <memory>. This makes no sense. I'm not very interested in
|
||||
// understanding why... these are old, bizarre platform configuration that we
|
||||
// should just let die.
|
||||
#if defined(MOZ_B2G) && defined(__GNUC__) && __GNUC__ == 4
|
||||
// See https://llvm.org/bugs/show_bug.cgi?id=25608 .
|
||||
#include <ciso646> // Include something innocuous to define _LIBCPP_VERISON if it's libc++.
|
||||
#if defined(__GNUC__) && __GNUC__ == 4 \
|
||||
&& ((defined(__arm__) && (defined(__ARM_NEON__) || defined(__ARM_NEON))) || defined(__aarch64__)) \
|
||||
&& defined(_LIBCPP_VERSION)
|
||||
typedef float float32_t;
|
||||
#include <memory>
|
||||
#endif
|
||||
|
@ -27,12 +31,6 @@
|
|||
#include "SkPostConfig.h"
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(SK_ARM_HAS_NEON)
|
||||
#include <arm_neon.h>
|
||||
#elif SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
|
||||
#include <immintrin.h>
|
||||
#endif
|
||||
// IWYU pragma: end_exports
|
||||
|
||||
#include <string.h>
|
||||
|
@ -141,45 +139,45 @@ inline void operator delete(void* p) {
|
|||
SK_API void SkDebugf(const char format[], ...);
|
||||
#endif
|
||||
|
||||
#define SkASSERT_RELEASE(cond) if(!(cond)) { SK_ABORT(#cond); }
|
||||
#define SkREQUIRE_SEMICOLON_AFTER(code) do { code } while (false)
|
||||
|
||||
#define SkASSERT_RELEASE(cond) \
|
||||
SkREQUIRE_SEMICOLON_AFTER(if (!(cond)) { SK_ABORT(#cond); } )
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
#define SkASSERT(cond) SkASSERT_RELEASE(cond)
|
||||
#define SkDEBUGFAIL(message) SkASSERT(false && message)
|
||||
#define SkASSERT(cond) \
|
||||
SkREQUIRE_SEMICOLON_AFTER(if (!(cond)) { SK_ABORT("assert(" #cond ")"); })
|
||||
#define SkASSERTF(cond, fmt, ...) \
|
||||
SkREQUIRE_SEMICOLON_AFTER(if (!(cond)) { \
|
||||
SkDebugf(fmt"\n", __VA_ARGS__); \
|
||||
SK_ABORT("assert(" #cond ")"); \
|
||||
})
|
||||
#define SkDEBUGFAIL(message) SK_ABORT(message)
|
||||
#define SkDEBUGFAILF(fmt, ...) SkASSERTF(false, fmt, ##__VA_ARGS__)
|
||||
#define SkDEBUGCODE(code) code
|
||||
#define SkDEBUGCODE(...) __VA_ARGS__
|
||||
#define SkDECLAREPARAM(type, var) , type var
|
||||
#define SkPARAM(var) , var
|
||||
// #define SkDEBUGF(args ) SkDebugf##args
|
||||
#define SkDEBUGF(args ) SkDebugf args
|
||||
#define SkAssertResult(cond) SkASSERT(cond)
|
||||
#else
|
||||
#define SkASSERT(cond)
|
||||
#define SkASSERTF(cond, fmt, ...)
|
||||
#define SkDEBUGFAIL(message)
|
||||
#define SkDEBUGCODE(code)
|
||||
#define SkDEBUGFAILF(fmt, ...)
|
||||
#define SkDEBUGCODE(...)
|
||||
#define SkDEBUGF(args)
|
||||
#define SkDECLAREPARAM(type, var)
|
||||
#define SkPARAM(var)
|
||||
|
||||
// unlike SkASSERT, this guy executes its condition in the non-debug build
|
||||
#define SkAssertResult(cond) cond
|
||||
// unlike SkASSERT, this guy executes its condition in the non-debug build.
|
||||
// The if is present so that this can be used with functions marked SK_WARN_UNUSED_RESULT.
|
||||
#define SkAssertResult(cond) if (cond) {} do {} while(false)
|
||||
#endif
|
||||
|
||||
// Legacy macro names for SK_ABORT
|
||||
#define SkFAIL(message) SK_ABORT(message)
|
||||
#define sk_throw() SK_ABORT("sk_throw")
|
||||
|
||||
// We want to evaluate cond only once, and inside the SkASSERT somewhere so we see its string form.
|
||||
// So we use the comma operator to make an SkDebugf that always returns false: we'll evaluate cond,
|
||||
// and if it's true the assert passes; if it's false, we'll print the message and the assert fails.
|
||||
#define SkASSERTF(cond, fmt, ...) SkASSERT((cond) || (SkDebugf(fmt"\n", __VA_ARGS__), false))
|
||||
|
||||
#ifdef SK_DEVELOPER
|
||||
#define SkDEVCODE(code) code
|
||||
#else
|
||||
#define SkDEVCODE(code)
|
||||
#endif
|
||||
|
||||
#ifdef SK_IGNORE_TO_STRING
|
||||
#define SK_TO_STRING_NONVIRT()
|
||||
#define SK_TO_STRING_VIRT()
|
||||
|
@ -286,7 +284,7 @@ template <typename D, typename S> D SkTo(S s) {
|
|||
|
||||
/** Returns 0 or 1 based on the condition
|
||||
*/
|
||||
#define SkToBool(cond) (!!(cond))
|
||||
#define SkToBool(cond) ((cond) != 0)
|
||||
|
||||
#define SK_MaxS16 32767
|
||||
#define SK_MinS16 -32767
|
||||
|
@ -356,6 +354,10 @@ typedef uint32_t SkFourByteTag;
|
|||
*/
|
||||
typedef int32_t SkUnichar;
|
||||
|
||||
/** 16 bit unsigned integer to hold a glyph index
|
||||
*/
|
||||
typedef uint16_t SkGlyphID;
|
||||
|
||||
/** 32 bit value to hold a millisecond duration
|
||||
* Note that SK_MSecMax is about 25 days.
|
||||
*/
|
||||
|
@ -387,7 +389,7 @@ typedef uint32_t SkMSec;
|
|||
|
||||
/** Faster than SkToBool for integral conditions. Returns 0 or 1
|
||||
*/
|
||||
static inline int Sk32ToBool(uint32_t n) {
|
||||
static inline constexpr int Sk32ToBool(uint32_t n) {
|
||||
return (n | (0-n)) >> 31;
|
||||
}
|
||||
|
||||
|
@ -426,11 +428,11 @@ static inline int32_t SkMin32(int32_t a, int32_t b) {
|
|||
return a;
|
||||
}
|
||||
|
||||
template <typename T> const T& SkTMin(const T& a, const T& b) {
|
||||
template <typename T> constexpr const T& SkTMin(const T& a, const T& b) {
|
||||
return (a < b) ? a : b;
|
||||
}
|
||||
|
||||
template <typename T> const T& SkTMax(const T& a, const T& b) {
|
||||
template <typename T> constexpr const T& SkTMax(const T& a, const T& b) {
|
||||
return (b < a) ? a : b;
|
||||
}
|
||||
|
||||
|
@ -446,7 +448,7 @@ static inline int32_t SkFastMin32(int32_t value, int32_t max) {
|
|||
}
|
||||
|
||||
/** Returns value pinned between min and max, inclusively. */
|
||||
template <typename T> static inline const T& SkTPin(const T& value, const T& min, const T& max) {
|
||||
template <typename T> static constexpr const T& SkTPin(const T& value, const T& min, const T& max) {
|
||||
return SkTMax(SkTMin(value, max), min);
|
||||
}
|
||||
|
||||
|
@ -461,6 +463,15 @@ enum class SkBudgeted : bool {
|
|||
kYes = true
|
||||
};
|
||||
|
||||
/**
|
||||
* Indicates whether a backing store needs to be an exact match or can be larger
|
||||
* than is strictly necessary
|
||||
*/
|
||||
enum class SkBackingFit {
|
||||
kApprox,
|
||||
kExact
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Use to combine multiple bits in a bitmask in a type safe way.
|
||||
|
|
|
@ -16,85 +16,120 @@
|
|||
#include "SkPixelSerializer.h"
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkWriter32.h"
|
||||
#include "../private/SkTHash.h"
|
||||
|
||||
class SkBitmap;
|
||||
class SkBitmapHeap;
|
||||
class SkDeduper;
|
||||
class SkFactorySet;
|
||||
class SkFlattenable;
|
||||
class SkNamedFactorySet;
|
||||
class SkRefCntSet;
|
||||
|
||||
class SkWriteBuffer {
|
||||
public:
|
||||
SkWriteBuffer() {}
|
||||
virtual ~SkWriteBuffer() {}
|
||||
|
||||
virtual bool isCrossProcess() const = 0;
|
||||
|
||||
virtual void writeByteArray(const void* data, size_t size) = 0;
|
||||
void writeDataAsByteArray(SkData* data) {
|
||||
this->writeByteArray(data->data(), data->size());
|
||||
}
|
||||
virtual void writeBool(bool value) = 0;
|
||||
virtual void writeScalar(SkScalar value) = 0;
|
||||
virtual void writeScalarArray(const SkScalar* value, uint32_t count) = 0;
|
||||
virtual void writeInt(int32_t value) = 0;
|
||||
virtual void writeIntArray(const int32_t* value, uint32_t count) = 0;
|
||||
virtual void writeUInt(uint32_t value) = 0;
|
||||
void write32(int32_t value) {
|
||||
this->writeInt(value);
|
||||
}
|
||||
virtual void writeString(const char* value) = 0;
|
||||
|
||||
virtual void writeFlattenable(const SkFlattenable* flattenable) = 0;
|
||||
virtual void writeColor(SkColor color) = 0;
|
||||
virtual void writeColorArray(const SkColor* color, uint32_t count) = 0;
|
||||
virtual void writeColor4f(const SkColor4f& color) = 0;
|
||||
virtual void writeColor4fArray(const SkColor4f* color, uint32_t count) = 0;
|
||||
virtual void writePoint(const SkPoint& point) = 0;
|
||||
virtual void writePointArray(const SkPoint* point, uint32_t count) = 0;
|
||||
virtual void writeMatrix(const SkMatrix& matrix) = 0;
|
||||
virtual void writeIRect(const SkIRect& rect) = 0;
|
||||
virtual void writeRect(const SkRect& rect) = 0;
|
||||
virtual void writeRegion(const SkRegion& region) = 0;
|
||||
virtual void writePath(const SkPath& path) = 0;
|
||||
virtual size_t writeStream(SkStream* stream, size_t length) = 0;
|
||||
virtual void writeBitmap(const SkBitmap& bitmap) = 0;
|
||||
virtual void writeImage(const SkImage*) = 0;
|
||||
virtual void writeTypeface(SkTypeface* typeface) = 0;
|
||||
virtual void writePaint(const SkPaint& paint) = 0;
|
||||
|
||||
void setDeduper(SkDeduper* deduper) { fDeduper = deduper; }
|
||||
|
||||
protected:
|
||||
SkDeduper* fDeduper = nullptr;
|
||||
};
|
||||
|
||||
/**
|
||||
* Concrete implementation that serializes to a flat binary blob.
|
||||
*/
|
||||
class SkBinaryWriteBuffer : public SkWriteBuffer {
|
||||
public:
|
||||
enum Flags {
|
||||
kCrossProcess_Flag = 1 << 0,
|
||||
kValidation_Flag = 1 << 1,
|
||||
kCrossProcess_Flag = 1 << 0,
|
||||
};
|
||||
|
||||
SkWriteBuffer(uint32_t flags = 0);
|
||||
SkWriteBuffer(void* initialStorage, size_t storageSize, uint32_t flags = 0);
|
||||
~SkWriteBuffer();
|
||||
SkBinaryWriteBuffer(uint32_t flags = 0);
|
||||
SkBinaryWriteBuffer(void* initialStorage, size_t storageSize, uint32_t flags = 0);
|
||||
~SkBinaryWriteBuffer();
|
||||
|
||||
bool isCrossProcess() const {
|
||||
return this->isValidating() || SkToBool(fFlags & kCrossProcess_Flag);
|
||||
bool isCrossProcess() const override {
|
||||
return SkToBool(fFlags & kCrossProcess_Flag);
|
||||
}
|
||||
|
||||
void write(const void* buffer, size_t bytes) {
|
||||
fWriter.write(buffer, bytes);
|
||||
}
|
||||
|
||||
SkWriter32* getWriter32() { return &fWriter; }
|
||||
void reset(void* storage = NULL, size_t storageSize = 0) {
|
||||
fWriter.reset(storage, storageSize);
|
||||
}
|
||||
|
||||
uint32_t* reserve(size_t size) { return fWriter.reserve(size); }
|
||||
|
||||
size_t bytesWritten() const { return fWriter.bytesWritten(); }
|
||||
|
||||
void writeByteArray(const void* data, size_t size);
|
||||
void writeDataAsByteArray(SkData* data) { this->writeByteArray(data->data(), data->size()); }
|
||||
void writeBool(bool value);
|
||||
void writeScalar(SkScalar value);
|
||||
void writeScalarArray(const SkScalar* value, uint32_t count);
|
||||
void writeInt(int32_t value);
|
||||
void writeIntArray(const int32_t* value, uint32_t count);
|
||||
void writeUInt(uint32_t value);
|
||||
void write32(int32_t value);
|
||||
void writeString(const char* value);
|
||||
void writeEncodedString(const void* value, size_t byteLength, SkPaint::TextEncoding encoding);
|
||||
void writeFunctionPtr(void* ptr) { fWriter.writePtr(ptr); }
|
||||
void writeByteArray(const void* data, size_t size) override;
|
||||
void writeBool(bool value) override;
|
||||
void writeScalar(SkScalar value) override;
|
||||
void writeScalarArray(const SkScalar* value, uint32_t count) override;
|
||||
void writeInt(int32_t value) override;
|
||||
void writeIntArray(const int32_t* value, uint32_t count) override;
|
||||
void writeUInt(uint32_t value) override;
|
||||
void writeString(const char* value) override;
|
||||
|
||||
void writeFlattenable(const SkFlattenable* flattenable);
|
||||
void writeColor(const SkColor& color);
|
||||
void writeColorArray(const SkColor* color, uint32_t count);
|
||||
void writePoint(const SkPoint& point);
|
||||
void writePointArray(const SkPoint* point, uint32_t count);
|
||||
void writeMatrix(const SkMatrix& matrix);
|
||||
void writeIRect(const SkIRect& rect);
|
||||
void writeRect(const SkRect& rect);
|
||||
void writeRegion(const SkRegion& region);
|
||||
void writePath(const SkPath& path);
|
||||
size_t writeStream(SkStream* stream, size_t length);
|
||||
void writeBitmap(const SkBitmap& bitmap);
|
||||
void writeImage(const SkImage*);
|
||||
void writeTypeface(SkTypeface* typeface);
|
||||
void writePaint(const SkPaint& paint) { paint.flatten(*this); }
|
||||
void writeFlattenable(const SkFlattenable* flattenable) override;
|
||||
void writeColor(SkColor color) override;
|
||||
void writeColorArray(const SkColor* color, uint32_t count) override;
|
||||
void writeColor4f(const SkColor4f& color) override;
|
||||
void writeColor4fArray(const SkColor4f* color, uint32_t count) override;
|
||||
void writePoint(const SkPoint& point) override;
|
||||
void writePointArray(const SkPoint* point, uint32_t count) override;
|
||||
void writeMatrix(const SkMatrix& matrix) override;
|
||||
void writeIRect(const SkIRect& rect) override;
|
||||
void writeRect(const SkRect& rect) override;
|
||||
void writeRegion(const SkRegion& region) override;
|
||||
void writePath(const SkPath& path) override;
|
||||
size_t writeStream(SkStream* stream, size_t length) override;
|
||||
void writeBitmap(const SkBitmap& bitmap) override;
|
||||
void writeImage(const SkImage*) override;
|
||||
void writeTypeface(SkTypeface* typeface) override;
|
||||
void writePaint(const SkPaint& paint) override;
|
||||
|
||||
bool writeToStream(SkWStream*);
|
||||
void writeToMemory(void* dst) { fWriter.flatten(dst); }
|
||||
|
||||
SkFactorySet* setFactoryRecorder(SkFactorySet*);
|
||||
SkNamedFactorySet* setNamedFactoryRecorder(SkNamedFactorySet*);
|
||||
|
||||
SkRefCntSet* getTypefaceRecorder() const { return fTFSet; }
|
||||
SkRefCntSet* setTypefaceRecorder(SkRefCntSet*);
|
||||
|
||||
/**
|
||||
* Set an SkBitmapHeap to store bitmaps rather than flattening.
|
||||
*
|
||||
* Incompatible with an SkPixelSerializer. If an SkPixelSerializer is set,
|
||||
* setting an SkBitmapHeap will set the SkPixelSerializer to NULL in release
|
||||
* and crash in debug.
|
||||
*/
|
||||
void setBitmapHeap(SkBitmapHeap*);
|
||||
|
||||
/**
|
||||
* Set an SkPixelSerializer to store an encoded representation of pixels,
|
||||
* e.g. SkBitmaps.
|
||||
|
@ -102,25 +137,21 @@ public:
|
|||
* Calls ref() on the serializer.
|
||||
*
|
||||
* TODO: Encode SkImage pixels as well.
|
||||
*
|
||||
* Incompatible with the SkBitmapHeap. If an encoder is set fBitmapHeap will
|
||||
* be set to NULL in release and crash in debug.
|
||||
*/
|
||||
void setPixelSerializer(SkPixelSerializer*);
|
||||
SkPixelSerializer* getPixelSerializer() const { return fPixelSerializer; }
|
||||
|
||||
private:
|
||||
bool isValidating() const { return SkToBool(fFlags & kValidation_Flag); }
|
||||
|
||||
const uint32_t fFlags;
|
||||
SkFactorySet* fFactorySet;
|
||||
SkNamedFactorySet* fNamedFactorySet;
|
||||
SkWriter32 fWriter;
|
||||
|
||||
SkBitmapHeap* fBitmapHeap;
|
||||
SkRefCntSet* fTFSet;
|
||||
|
||||
SkAutoTUnref<SkPixelSerializer> fPixelSerializer;
|
||||
|
||||
// Only used if we do not have an fFactorySet
|
||||
SkTHashMap<SkString, uint32_t> fFlattenableDict;
|
||||
};
|
||||
|
||||
#endif // SkWriteBuffer_DEFINED
|
||||
|
|
|
@ -51,12 +51,6 @@ public:
|
|||
fExternal = external;
|
||||
}
|
||||
|
||||
// Returns the current buffer.
|
||||
// The pointer may be invalidated by any future write calls.
|
||||
const uint32_t* contiguousArray() const {
|
||||
return (uint32_t*)fData;
|
||||
}
|
||||
|
||||
// size MUST be multiple of 4
|
||||
uint32_t* reserve(size_t size) {
|
||||
SkASSERT(SkAlign4(size) == size);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
/*
|
||||
* Copyright 2006 The Android Open Source Project
|
||||
*
|
||||
|
@ -6,18 +5,21 @@
|
|||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SkXfermode_DEFINED
|
||||
#define SkXfermode_DEFINED
|
||||
|
||||
#include "SkFlattenable.h"
|
||||
#include "SkBlendMode.h"
|
||||
#include "SkColor.h"
|
||||
#include "SkFlattenable.h"
|
||||
|
||||
class GrFragmentProcessor;
|
||||
class GrTexture;
|
||||
class GrXPFactory;
|
||||
class SkRasterPipeline;
|
||||
class SkString;
|
||||
|
||||
struct SkArithmeticParams;
|
||||
|
||||
struct SkPM4f;
|
||||
typedef SkPM4f (*SkXfermodeProc4f)(const SkPM4f& src, const SkPM4f& dst);
|
||||
|
||||
|
@ -113,6 +115,9 @@ public:
|
|||
* Gets the name of the Mode as a string.
|
||||
*/
|
||||
static const char* ModeName(Mode);
|
||||
static const char* ModeName(SkBlendMode mode) {
|
||||
return ModeName(Mode(mode));
|
||||
}
|
||||
|
||||
/**
|
||||
* If the xfermode is one of the modes in the Mode enum, then asMode()
|
||||
|
@ -158,6 +163,31 @@ public:
|
|||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Skia maintains global xfermode objects corresponding to each BlendMode. This returns a
|
||||
* ptr to that global xfermode (or null if the mode is srcover). Thus the caller may use
|
||||
* the returned ptr, but it should leave its refcnt untouched.
|
||||
*/
|
||||
static SkXfermode* Peek(SkBlendMode mode) {
|
||||
sk_sp<SkXfermode> xfer = Make(mode);
|
||||
if (!xfer) {
|
||||
SkASSERT(SkBlendMode::kSrcOver == mode);
|
||||
return nullptr;
|
||||
}
|
||||
SkASSERT(!xfer->unique());
|
||||
return xfer.get();
|
||||
}
|
||||
|
||||
static sk_sp<SkXfermode> Make(SkBlendMode bm) {
|
||||
return Make((Mode)bm);
|
||||
}
|
||||
|
||||
SkBlendMode blend() const {
|
||||
Mode mode;
|
||||
SkAssertResult(this->asMode(&mode));
|
||||
return (SkBlendMode)mode;
|
||||
}
|
||||
|
||||
/** Return a function pointer to a routine that applies the specified
|
||||
porter-duff transfer mode.
|
||||
*/
|
||||
|
@ -166,6 +196,8 @@ public:
|
|||
|
||||
virtual SkXfermodeProc4f getProc4f() const;
|
||||
|
||||
bool appendStages(SkRasterPipeline*) const;
|
||||
|
||||
/**
|
||||
* If the specified mode can be represented by a pair of Coeff, then return
|
||||
* true and set (if not NULL) the corresponding coeffs. If the mode is
|
||||
|
@ -214,22 +246,23 @@ public:
|
|||
static bool IsOpaque(const sk_sp<SkXfermode>& xfer, SrcColorOpacity opacityType) {
|
||||
return IsOpaque(xfer.get(), opacityType);
|
||||
}
|
||||
static bool IsOpaque(SkBlendMode, SrcColorOpacity);
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
/** Used by the SkXfermodeImageFilter to blend two colors via a GrFragmentProcessor.
|
||||
The input to the returned FP is the src color. The dst color is
|
||||
provided by the dst param which becomes a child FP of the returned FP.
|
||||
provided by the dst param which becomes a child FP of the returned FP.
|
||||
It is legal for the function to return a null output. This indicates that
|
||||
the output of the blend is simply the src color.
|
||||
*/
|
||||
virtual const GrFragmentProcessor* getFragmentProcessorForImageFilter(
|
||||
const GrFragmentProcessor* dst) const;
|
||||
virtual sk_sp<GrFragmentProcessor> makeFragmentProcessorForImageFilter(
|
||||
sk_sp<GrFragmentProcessor> dst) const;
|
||||
|
||||
/** A subclass must implement this factory function to work with the GPU backend.
|
||||
The xfermode will return a factory for which the caller will get a ref. It is up
|
||||
/** A subclass must implement this factory function to work with the GPU backend.
|
||||
The xfermode will return a factory for which the caller will get a ref. It is up
|
||||
to the caller to install it. XferProcessors cannot use a background texture.
|
||||
*/
|
||||
virtual GrXPFactory* asXPFactory() const;
|
||||
virtual sk_sp<GrXPFactory> asXPFactory() const;
|
||||
#endif
|
||||
|
||||
SK_TO_STRING_PUREVIRT()
|
||||
|
@ -248,27 +281,28 @@ public:
|
|||
return GetD32Proc(xfer.get(), flags);
|
||||
}
|
||||
|
||||
enum D64Flags {
|
||||
kSrcIsOpaque_D64Flag = 1 << 0,
|
||||
kSrcIsSingle_D64Flag = 1 << 1,
|
||||
kDstIsFloat16_D64Flag = 1 << 2, // else U16 bit components
|
||||
enum F16Flags {
|
||||
kSrcIsOpaque_F16Flag = 1 << 0,
|
||||
kSrcIsSingle_F16Flag = 1 << 1,
|
||||
};
|
||||
typedef void (*D64Proc)(const SkXfermode*, uint64_t dst[], const SkPM4f src[], int count,
|
||||
typedef void (*F16Proc)(const SkXfermode*, uint64_t dst[], const SkPM4f src[], int count,
|
||||
const SkAlpha coverage[]);
|
||||
static D64Proc GetD64Proc(SkXfermode*, uint32_t flags);
|
||||
static D64Proc GetD64Proc(const sk_sp<SkXfermode>& xfer, uint32_t flags) {
|
||||
return GetD64Proc(xfer.get(), flags);
|
||||
static F16Proc GetF16Proc(SkXfermode*, uint32_t flags);
|
||||
static F16Proc GetF16Proc(const sk_sp<SkXfermode>& xfer, uint32_t flags) {
|
||||
return GetF16Proc(xfer.get(), flags);
|
||||
}
|
||||
|
||||
enum LCDFlags {
|
||||
kSrcIsOpaque_LCDFlag = 1 << 0, // else src(s) may have alpha < 1
|
||||
kSrcIsSingle_LCDFlag = 1 << 1, // else src[count]
|
||||
kDstIsLinearInt_LCDFlag = 1 << 2, // else srgb/half-float
|
||||
kDstIsSRGB_LCDFlag = 1 << 2, // else l32 or f16
|
||||
};
|
||||
typedef void (*LCD32Proc)(uint32_t* dst, const SkPM4f* src, int count, const uint16_t lcd[]);
|
||||
typedef void (*LCD64Proc)(uint64_t* dst, const SkPM4f* src, int count, const uint16_t lcd[]);
|
||||
typedef void (*LCDF16Proc)(uint64_t* dst, const SkPM4f* src, int count, const uint16_t lcd[]);
|
||||
static LCD32Proc GetLCD32Proc(uint32_t flags);
|
||||
static LCD64Proc GetLCD64Proc(uint32_t) { return nullptr; }
|
||||
static LCDF16Proc GetLCDF16Proc(uint32_t) { return nullptr; }
|
||||
|
||||
virtual bool isArithmetic(SkArithmeticParams*) const { return false; }
|
||||
|
||||
protected:
|
||||
SkXfermode() {}
|
||||
|
@ -283,7 +317,8 @@ protected:
|
|||
virtual SkPMColor xferColor(SkPMColor src, SkPMColor dst) const;
|
||||
|
||||
virtual D32Proc onGetD32Proc(uint32_t flags) const;
|
||||
virtual D64Proc onGetD64Proc(uint32_t flags) const;
|
||||
virtual F16Proc onGetF16Proc(uint32_t flags) const;
|
||||
virtual bool onAppendStages(SkRasterPipeline*) const;
|
||||
|
||||
private:
|
||||
enum {
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
#define SkAlphaThresholdFilter_DEFINED
|
||||
|
||||
#include "SkImageFilter.h"
|
||||
#include "SkRegion.h"
|
||||
|
||||
class SkRegion;
|
||||
|
||||
class SK_API SkAlphaThresholdFilter {
|
||||
public:
|
||||
|
@ -21,7 +22,8 @@ public:
|
|||
* source image.
|
||||
*/
|
||||
static sk_sp<SkImageFilter> Make(const SkRegion& region, SkScalar innerMin,
|
||||
SkScalar outerMax, sk_sp<SkImageFilter> input);
|
||||
SkScalar outerMax, sk_sp<SkImageFilter> input,
|
||||
const SkImageFilter::CropRect* cropRect = nullptr);
|
||||
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_IMAGEFILTER_PTR
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#include "SkScalar.h"
|
||||
#include "SkXfermode.h"
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_ARITHMETICMODE
|
||||
|
||||
class SK_API SkArithmeticMode {
|
||||
public:
|
||||
/**
|
||||
|
@ -38,3 +40,5 @@ private:
|
|||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -9,44 +9,23 @@
|
|||
#define SkBlurImageFilter_DEFINED
|
||||
|
||||
#include "SkImageFilter.h"
|
||||
#include "SkSize.h"
|
||||
|
||||
class SK_API SkBlurImageFilter : public SkImageFilter {
|
||||
class SK_API SkBlurImageFilter {
|
||||
public:
|
||||
static sk_sp<SkImageFilter> Make(SkScalar sigmaX, SkScalar sigmaY, sk_sp<SkImageFilter> input,
|
||||
const CropRect* cropRect = nullptr) {
|
||||
if (0 == sigmaX && 0 == sigmaY && nullptr == cropRect) {
|
||||
return input;
|
||||
}
|
||||
return sk_sp<SkImageFilter>(new SkBlurImageFilter(sigmaX, sigmaY, input, cropRect));
|
||||
static sk_sp<SkImageFilter> Make(SkScalar sigmaX, SkScalar sigmaY,
|
||||
sk_sp<SkImageFilter> input,
|
||||
const SkImageFilter::CropRect* cropRect = nullptr) {
|
||||
return SkImageFilter::MakeBlur(sigmaX, sigmaY, input, cropRect);
|
||||
}
|
||||
|
||||
SkRect computeFastBounds(const SkRect&) const override;
|
||||
|
||||
SK_TO_STRING_OVERRIDE()
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBlurImageFilter)
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_IMAGEFILTER_PTR
|
||||
static SkImageFilter* Create(SkScalar sigmaX, SkScalar sigmaY, SkImageFilter* input = nullptr,
|
||||
const CropRect* cropRect = nullptr) {
|
||||
return Make(sigmaX, sigmaY, sk_ref_sp<SkImageFilter>(input), cropRect).release();
|
||||
static SkImageFilter* Create(SkScalar sigmaX, SkScalar sigmaY,
|
||||
SkImageFilter * input = nullptr,
|
||||
const SkImageFilter::CropRect* cropRect = nullptr) {
|
||||
return SkImageFilter::MakeBlur(sigmaX, sigmaY, sk_ref_sp<SkImageFilter>(input),
|
||||
cropRect).release();
|
||||
}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
void flatten(SkWriteBuffer&) const override;
|
||||
sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&,
|
||||
SkIPoint* offset) const override;
|
||||
SkIRect onFilterNodeBounds(const SkIRect& src, const SkMatrix&, MapDirection) const override;
|
||||
|
||||
private:
|
||||
SkBlurImageFilter(SkScalar sigmaX,
|
||||
SkScalar sigmaY,
|
||||
sk_sp<SkImageFilter> input,
|
||||
const CropRect* cropRect);
|
||||
|
||||
SkSize fSigma;
|
||||
typedef SkImageFilter INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -32,13 +32,21 @@ public:
|
|||
};
|
||||
|
||||
/** Create a blur maskfilter.
|
||||
* @param style The SkBlurStyle to use
|
||||
* @param sigma Standard deviation of the Gaussian blur to apply. Must be > 0.
|
||||
* @param flags Flags to use - defaults to none
|
||||
* @param style The SkBlurStyle to use
|
||||
* @param sigma Standard deviation of the Gaussian blur to apply. Must be > 0.
|
||||
* @param occluder The rect for which no pixels need be drawn (b.c. it will be overdrawn
|
||||
* with some opaque object. This is just a hint which backends are free to
|
||||
* ignore.
|
||||
* @param flags Flags to use - defaults to none
|
||||
* @return The new blur maskfilter
|
||||
*/
|
||||
static sk_sp<SkMaskFilter> Make(SkBlurStyle style, SkScalar sigma,
|
||||
uint32_t flags = kNone_BlurFlag);
|
||||
const SkRect& occluder, uint32_t flags = kNone_BlurFlag);
|
||||
|
||||
static sk_sp<SkMaskFilter> Make(SkBlurStyle style, SkScalar sigma,
|
||||
uint32_t flags = kNone_BlurFlag) {
|
||||
return Make(style, sigma, SkRect::MakeEmpty(), flags);
|
||||
}
|
||||
|
||||
/** Create an emboss maskfilter
|
||||
@param blurSigma standard deviation of the Gaussian blur to apply
|
||||
|
@ -65,6 +73,28 @@ public:
|
|||
SkScalar blurRadius);
|
||||
#endif
|
||||
|
||||
static const int kMaxDivisions = 6;
|
||||
|
||||
// This method computes all the parameters for drawing a partially occluded nine-patched
|
||||
// blurred rrect mask:
|
||||
// rrectToDraw - the integerized rrect to draw in the mask
|
||||
// widthHeight - how large to make the mask (rrectToDraw will be centered in this coord sys)
|
||||
// rectXs, rectYs - the x & y coordinates of the covering geometry lattice
|
||||
// texXs, texYs - the texture coordinate at each point in rectXs & rectYs
|
||||
// numXs, numYs - number of coordinates in the x & y directions
|
||||
// skipMask - bit mask that contains a 1-bit whenever one of the cells is occluded
|
||||
// It returns true if 'devRRect' is nine-patchable
|
||||
static bool ComputeBlurredRRectParams(const SkRRect& srcRRect, const SkRRect& devRRect,
|
||||
const SkRect& occluder,
|
||||
SkScalar sigma, SkScalar xformedSigma,
|
||||
SkRRect* rrectToDraw,
|
||||
SkISize* widthHeight,
|
||||
SkScalar rectXs[kMaxDivisions],
|
||||
SkScalar rectYs[kMaxDivisions],
|
||||
SkScalar texXs[kMaxDivisions],
|
||||
SkScalar texYs[kMaxDivisions],
|
||||
int* numXs, int* numYs, uint32_t* skipMask);
|
||||
|
||||
SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
|
||||
|
||||
private:
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
#include "SkColorFilter.h"
|
||||
#include "SkData.h"
|
||||
#include "../private/SkMutex.h"
|
||||
#include "../private/SkOnce.h"
|
||||
#include "../private/SkTemplates.h"
|
||||
|
||||
class SK_API SkColorCubeFilter : public SkColorFilter {
|
||||
|
@ -30,7 +30,7 @@ public:
|
|||
uint32_t getFlags() const override;
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
const GrFragmentProcessor* asFragmentProcessor(GrContext*) const override;
|
||||
sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*) const override;
|
||||
#endif
|
||||
|
||||
SK_TO_STRING_OVERRIDE()
|
||||
|
@ -65,8 +65,7 @@ private:
|
|||
const int fCubeDimension;
|
||||
|
||||
// Make sure we only initialize the caches once.
|
||||
SkMutex fLutsMutex;
|
||||
bool fLutsInited;
|
||||
SkOnce fLutsInitOnce;
|
||||
|
||||
static void initProcessingLuts(ColorCubeProcesingCache* cache);
|
||||
};
|
||||
|
|
|
@ -33,9 +33,10 @@ public:
|
|||
|
||||
protected:
|
||||
void flatten(SkWriteBuffer&) const override;
|
||||
bool onFilterImageDeprecated(Proxy*, const SkBitmap& src, const Context&, SkBitmap* result,
|
||||
SkIPoint* loc) const override;
|
||||
sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&,
|
||||
SkIPoint* offset) const override;
|
||||
bool onIsColorFilterNode(SkColorFilter**) const override;
|
||||
bool onCanHandleComplexCTM() const override { return true; }
|
||||
bool affectsTransparentBlack() const override;
|
||||
|
||||
private:
|
||||
|
|
|
@ -12,16 +12,8 @@
|
|||
|
||||
class SK_API SkComposeImageFilter : public SkImageFilter {
|
||||
public:
|
||||
static sk_sp<SkImageFilter> Make(sk_sp<SkImageFilter> outer, sk_sp<SkImageFilter> inner) {
|
||||
if (!outer) {
|
||||
return inner;
|
||||
}
|
||||
if (!inner) {
|
||||
return outer;
|
||||
}
|
||||
sk_sp<SkImageFilter> inputs[2] = { std::move(outer), std::move(inner) };
|
||||
return sk_sp<SkImageFilter>(new SkComposeImageFilter(inputs));
|
||||
}
|
||||
static sk_sp<SkImageFilter> Make(sk_sp<SkImageFilter> outer, sk_sp<SkImageFilter> inner);
|
||||
|
||||
SkRect computeFastBounds(const SkRect& src) const override;
|
||||
|
||||
SK_TO_STRING_OVERRIDE()
|
||||
|
@ -42,6 +34,7 @@ protected:
|
|||
sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&,
|
||||
SkIPoint* offset) const override;
|
||||
SkIRect onFilterBounds(const SkIRect&, const SkMatrix&, MapDirection) const override;
|
||||
bool onCanHandleComplexCTM() const override { return true; }
|
||||
|
||||
private:
|
||||
typedef SkImageFilter INHERITED;
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#define SkDisplacementMapEffect_DEFINED
|
||||
|
||||
#include "SkImageFilter.h"
|
||||
#include "SkBitmap.h"
|
||||
|
||||
class SK_API SkDisplacementMapEffect : public SkImageFilter {
|
||||
public:
|
||||
|
@ -21,39 +20,45 @@ public:
|
|||
kA_ChannelSelectorType
|
||||
};
|
||||
|
||||
~SkDisplacementMapEffect();
|
||||
~SkDisplacementMapEffect() override;
|
||||
|
||||
static SkImageFilter* Create(ChannelSelectorType xChannelSelector,
|
||||
ChannelSelectorType yChannelSelector,
|
||||
SkScalar scale, SkImageFilter* displacement,
|
||||
SkImageFilter* color = NULL,
|
||||
const CropRect* cropRect = NULL);
|
||||
static sk_sp<SkImageFilter> Make(ChannelSelectorType xChannelSelector,
|
||||
ChannelSelectorType yChannelSelector,
|
||||
SkScalar scale,
|
||||
sk_sp<SkImageFilter> displacement,
|
||||
sk_sp<SkImageFilter> color,
|
||||
const CropRect* cropRect = nullptr);
|
||||
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDisplacementMapEffect)
|
||||
|
||||
bool onFilterImageDeprecated(Proxy* proxy,
|
||||
const SkBitmap& src,
|
||||
const Context& ctx,
|
||||
SkBitmap* dst,
|
||||
SkIPoint* offset) const override;
|
||||
SkRect computeFastBounds(const SkRect& src) const override;
|
||||
|
||||
virtual SkIRect onFilterBounds(const SkIRect& src, const SkMatrix&,
|
||||
MapDirection) const override;
|
||||
SkIRect onFilterNodeBounds(const SkIRect&, const SkMatrix&, MapDirection) const override;
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
bool canFilterImageGPU() const override { return true; }
|
||||
bool filterImageGPUDeprecated(Proxy* proxy, const SkBitmap& src, const Context& ctx,
|
||||
SkBitmap* result, SkIPoint* offset) const override;
|
||||
#endif
|
||||
|
||||
SK_TO_STRING_OVERRIDE()
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_IMAGEFILTER_PTR
|
||||
static SkImageFilter* Create(ChannelSelectorType xChannelSelector,
|
||||
ChannelSelectorType yChannelSelector,
|
||||
SkScalar scale, SkImageFilter* displacement,
|
||||
SkImageFilter* color = nullptr,
|
||||
const CropRect* cropRect = nullptr) {
|
||||
return Make(xChannelSelector, yChannelSelector, scale,
|
||||
sk_ref_sp<SkImageFilter>(displacement),
|
||||
sk_ref_sp<SkImageFilter>(color),
|
||||
cropRect).release();
|
||||
}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&,
|
||||
SkIPoint* offset) const override;
|
||||
|
||||
SkDisplacementMapEffect(ChannelSelectorType xChannelSelector,
|
||||
ChannelSelectorType yChannelSelector,
|
||||
SkScalar scale, SkImageFilter* inputs[2],
|
||||
SkScalar scale, sk_sp<SkImageFilter> inputs[2],
|
||||
const CropRect* cropRect);
|
||||
void flatten(SkWriteBuffer&) const override;
|
||||
|
||||
|
|
|
@ -26,12 +26,7 @@ public:
|
|||
static sk_sp<SkImageFilter> Make(SkScalar dx, SkScalar dy, SkScalar sigmaX, SkScalar sigmaY,
|
||||
SkColor color, ShadowMode shadowMode,
|
||||
sk_sp<SkImageFilter> input,
|
||||
const CropRect* cropRect = nullptr) {
|
||||
return sk_sp<SkImageFilter>(new SkDropShadowImageFilter(dx, dy, sigmaX, sigmaY,
|
||||
color, shadowMode,
|
||||
std::move(input),
|
||||
cropRect));
|
||||
}
|
||||
const CropRect* cropRect = nullptr);
|
||||
|
||||
SkRect computeFastBounds(const SkRect&) const override;
|
||||
SK_TO_STRING_OVERRIDE()
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkGammaColorFilter_DEFINED
|
||||
#define SkGammaColorFilter_DEFINED
|
||||
|
||||
#include "SkColorFilter.h"
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
// This colorfilter can be used to perform pixel-by-pixel conversion between linear and
|
||||
// power-law color spaces. A gamma of 2.2 is interpreted to mean convert from sRGB to linear
|
||||
// while a gamma of 1/2.2 is interpreted to mean convert from linear to sRGB. Any other
|
||||
// values are just directly applied (i.e., out = in^gamma)
|
||||
//
|
||||
// More complicated color space mapping (i.e., ICC profiles) should be handled via the
|
||||
// SkColorSpace object.
|
||||
class SK_API SkGammaColorFilter : public SkColorFilter {
|
||||
public:
|
||||
static sk_sp<SkColorFilter> Make(SkScalar gamma);
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_COLORFILTER_PTR
|
||||
static SkColorFilter* Create(SkScalar gamma) { return Make(gamma).release(); }
|
||||
#endif
|
||||
|
||||
void filterSpan(const SkPMColor src[], int count, SkPMColor[]) const override;
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*) const override;
|
||||
#endif
|
||||
|
||||
SK_TO_STRING_OVERRIDE()
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLumaColorFilter)
|
||||
|
||||
protected:
|
||||
void flatten(SkWriteBuffer&) const override;
|
||||
|
||||
private:
|
||||
SkGammaColorFilter(SkScalar gamma);
|
||||
|
||||
SkScalar fGamma;
|
||||
typedef SkColorFilter INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkGaussianEdgeShader_DEFINED
|
||||
#define SkGaussianEdgeShader_DEFINED
|
||||
|
||||
#include "SkShader.h"
|
||||
|
||||
class SK_API SkGaussianEdgeShader {
|
||||
public:
|
||||
/** Returns a shader that applies a Gaussian blur depending on distance to the edge
|
||||
* Currently this is only useable with Circle and RRect shapes on the GPU backend.
|
||||
* Raster will draw nothing.
|
||||
*/
|
||||
static sk_sp<SkShader> Make();
|
||||
|
||||
SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
|
||||
|
||||
private:
|
||||
SkGaussianEdgeShader(); // can't be instantiated
|
||||
};
|
||||
|
||||
#endif
|
|
@ -26,13 +26,9 @@ public:
|
|||
kInterpolateColorsInPremul_Flag = 1 << 0,
|
||||
};
|
||||
|
||||
/** Returns a shader that generates a linear gradient between the two
|
||||
specified points.
|
||||
/** Returns a shader that generates a linear gradient between the two specified points.
|
||||
<p />
|
||||
CreateLinear returns a shader with a reference count of 1.
|
||||
The caller should decrement the shader's reference count when done with the shader.
|
||||
It is an error for count to be < 2.
|
||||
@param pts The start and end points for the gradient.
|
||||
@param pts The start and end points for the gradient.
|
||||
@param colors The array[count] of colors, to be distributed between the two points
|
||||
@param pos May be NULL. array[count] of SkScalars, or NULL, of the relative position of
|
||||
each corresponding color in the colors array. If this is NULL,
|
||||
|
@ -52,11 +48,30 @@ public:
|
|||
return MakeLinear(pts, colors, pos, count, mode, 0, NULL);
|
||||
}
|
||||
|
||||
/** Returns a shader that generates a linear gradient between the two specified points.
|
||||
<p />
|
||||
@param pts The start and end points for the gradient.
|
||||
@param colors The array[count] of colors, to be distributed between the two points
|
||||
@param pos May be NULL. array[count] of SkScalars, or NULL, of the relative position of
|
||||
each corresponding color in the colors array. If this is NULL,
|
||||
the the colors are distributed evenly between the start and end point.
|
||||
If this is not null, the values must begin with 0, end with 1.0, and
|
||||
intermediate values must be strictly increasing.
|
||||
@param count Must be >=2. The number of colors (and pos if not NULL) entries.
|
||||
@param mode The tiling mode
|
||||
*/
|
||||
static sk_sp<SkShader> MakeLinear(const SkPoint pts[2],
|
||||
const SkColor4f colors[], sk_sp<SkColorSpace> colorSpace,
|
||||
const SkScalar pos[], int count, SkShader::TileMode mode,
|
||||
uint32_t flags, const SkMatrix* localMatrix);
|
||||
static sk_sp<SkShader> MakeLinear(const SkPoint pts[2],
|
||||
const SkColor4f colors[], sk_sp<SkColorSpace> colorSpace,
|
||||
const SkScalar pos[], int count, SkShader::TileMode mode) {
|
||||
return MakeLinear(pts, colors, std::move(colorSpace), pos, count, mode, 0, NULL);
|
||||
}
|
||||
|
||||
/** Returns a shader that generates a radial gradient given the center and radius.
|
||||
<p />
|
||||
CreateRadial returns a shader with a reference count of 1.
|
||||
The caller should decrement the shader's reference count when done with the shader.
|
||||
It is an error for colorCount to be < 2, or for radius to be <= 0.
|
||||
@param center The center of the circle for this gradient
|
||||
@param radius Must be positive. The radius of the circle for this gradient
|
||||
@param colors The array[count] of colors, to be distributed between the center and edge of the circle
|
||||
|
@ -78,6 +93,29 @@ public:
|
|||
return MakeRadial(center, radius, colors, pos, count, mode, 0, NULL);
|
||||
}
|
||||
|
||||
/** Returns a shader that generates a radial gradient given the center and radius.
|
||||
<p />
|
||||
@param center The center of the circle for this gradient
|
||||
@param radius Must be positive. The radius of the circle for this gradient
|
||||
@param colors The array[count] of colors, to be distributed between the center and edge of the circle
|
||||
@param pos May be NULL. The array[count] of SkScalars, or NULL, of the relative position of
|
||||
each corresponding color in the colors array. If this is NULL,
|
||||
the the colors are distributed evenly between the center and edge of the circle.
|
||||
If this is not null, the values must begin with 0, end with 1.0, and
|
||||
intermediate values must be strictly increasing.
|
||||
@param count Must be >= 2. The number of colors (and pos if not NULL) entries
|
||||
@param mode The tiling mode
|
||||
*/
|
||||
static sk_sp<SkShader> MakeRadial(const SkPoint& center, SkScalar radius,
|
||||
const SkColor4f colors[], sk_sp<SkColorSpace> colorSpace,
|
||||
const SkScalar pos[], int count, SkShader::TileMode mode,
|
||||
uint32_t flags, const SkMatrix* localMatrix);
|
||||
static sk_sp<SkShader> MakeRadial(const SkPoint& center, SkScalar radius,
|
||||
const SkColor4f colors[], sk_sp<SkColorSpace> colorSpace,
|
||||
const SkScalar pos[], int count, SkShader::TileMode mode) {
|
||||
return MakeRadial(center, radius, colors, std::move(colorSpace), pos, count, mode, 0, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a shader that generates a conical gradient given two circles, or
|
||||
* returns NULL if the inputs are invalid. The gradient interprets the
|
||||
|
@ -97,11 +135,29 @@ public:
|
|||
0, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a shader that generates a conical gradient given two circles, or
|
||||
* returns NULL if the inputs are invalid. The gradient interprets the
|
||||
* two circles according to the following HTML spec.
|
||||
* http://dev.w3.org/html5/2dcontext/#dom-context-2d-createradialgradient
|
||||
*/
|
||||
static sk_sp<SkShader> MakeTwoPointConical(const SkPoint& start, SkScalar startRadius,
|
||||
const SkPoint& end, SkScalar endRadius,
|
||||
const SkColor4f colors[],
|
||||
sk_sp<SkColorSpace> colorSpace, const SkScalar pos[],
|
||||
int count, SkShader::TileMode mode,
|
||||
uint32_t flags, const SkMatrix* localMatrix);
|
||||
static sk_sp<SkShader> MakeTwoPointConical(const SkPoint& start, SkScalar startRadius,
|
||||
const SkPoint& end, SkScalar endRadius,
|
||||
const SkColor4f colors[],
|
||||
sk_sp<SkColorSpace> colorSpace, const SkScalar pos[],
|
||||
int count, SkShader::TileMode mode) {
|
||||
return MakeTwoPointConical(start, startRadius, end, endRadius, colors,
|
||||
std::move(colorSpace), pos, count, mode, 0, NULL);
|
||||
}
|
||||
|
||||
/** Returns a shader that generates a sweep gradient given a center.
|
||||
<p />
|
||||
CreateSweep returns a shader with a reference count of 1.
|
||||
The caller should decrement the shader's reference count when done with the shader.
|
||||
It is an error for colorCount to be < 2.
|
||||
@param cx The X coordinate of the center of the sweep
|
||||
@param cx The Y coordinate of the center of the sweep
|
||||
@param colors The array[count] of colors, to be distributed around the center.
|
||||
|
@ -120,6 +176,28 @@ public:
|
|||
return MakeSweep(cx, cy, colors, pos, count, 0, NULL);
|
||||
}
|
||||
|
||||
/** Returns a shader that generates a sweep gradient given a center.
|
||||
<p />
|
||||
@param cx The X coordinate of the center of the sweep
|
||||
@param cx The Y coordinate of the center of the sweep
|
||||
@param colors The array[count] of colors, to be distributed around the center.
|
||||
@param pos May be NULL. The array[count] of SkScalars, or NULL, of the relative position of
|
||||
each corresponding color in the colors array. If this is NULL,
|
||||
the the colors are distributed evenly between the center and edge of the circle.
|
||||
If this is not null, the values must begin with 0, end with 1.0, and
|
||||
intermediate values must be strictly increasing.
|
||||
@param count Must be >= 2. The number of colors (and pos if not NULL) entries
|
||||
*/
|
||||
static sk_sp<SkShader> MakeSweep(SkScalar cx, SkScalar cy,
|
||||
const SkColor4f colors[], sk_sp<SkColorSpace> colorSpace,
|
||||
const SkScalar pos[], int count,
|
||||
uint32_t flags, const SkMatrix* localMatrix);
|
||||
static sk_sp<SkShader> MakeSweep(SkScalar cx, SkScalar cy,
|
||||
const SkColor4f colors[], sk_sp<SkColorSpace> colorSpace,
|
||||
const SkScalar pos[], int count) {
|
||||
return MakeSweep(cx, cy, colors, std::move(colorSpace), pos, count, 0, NULL);
|
||||
}
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_CREATESHADER_PTR
|
||||
static SkShader* CreateLinear(const SkPoint pts[2],
|
||||
const SkColor colors[], const SkScalar pos[], int count,
|
||||
|
|
|
@ -13,25 +13,11 @@
|
|||
|
||||
class SK_API SkImageSource : public SkImageFilter {
|
||||
public:
|
||||
static sk_sp<SkImageFilter> Make(sk_sp<SkImage> image) {
|
||||
if (!image) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return sk_sp<SkImageFilter>(new SkImageSource(std::move(image)));
|
||||
}
|
||||
static sk_sp<SkImageFilter> Make(sk_sp<SkImage> image);
|
||||
static sk_sp<SkImageFilter> Make(sk_sp<SkImage> image,
|
||||
const SkRect& srcRect,
|
||||
const SkRect& dstRect,
|
||||
SkFilterQuality filterQuality) {
|
||||
if (!image) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return sk_sp<SkImageFilter>(new SkImageSource(std::move(image),
|
||||
srcRect, dstRect,
|
||||
filterQuality));
|
||||
}
|
||||
SkFilterQuality filterQuality);
|
||||
|
||||
SkRect computeFastBounds(const SkRect& src) const override;
|
||||
|
||||
|
|
|
@ -17,34 +17,77 @@ struct SkPoint3;
|
|||
|
||||
class SK_API SkLightingImageFilter : public SkImageFilter {
|
||||
public:
|
||||
static SkImageFilter* CreateDistantLitDiffuse(const SkPoint3& direction,
|
||||
static sk_sp<SkImageFilter> MakeDistantLitDiffuse(const SkPoint3& direction,
|
||||
SkColor lightColor, SkScalar surfaceScale, SkScalar kd,
|
||||
SkImageFilter* input = NULL, const CropRect* cropRect = NULL);
|
||||
static SkImageFilter* CreatePointLitDiffuse(const SkPoint3& location,
|
||||
sk_sp<SkImageFilter> input, const CropRect* cropRect = nullptr);
|
||||
static sk_sp<SkImageFilter> MakePointLitDiffuse(const SkPoint3& location,
|
||||
SkColor lightColor, SkScalar surfaceScale, SkScalar kd,
|
||||
SkImageFilter* input = NULL, const CropRect* cropRect = NULL);
|
||||
static SkImageFilter* CreateSpotLitDiffuse(const SkPoint3& location,
|
||||
sk_sp<SkImageFilter> input, const CropRect* cropRect = nullptr);
|
||||
static sk_sp<SkImageFilter> MakeSpotLitDiffuse(const SkPoint3& location,
|
||||
const SkPoint3& target, SkScalar specularExponent, SkScalar cutoffAngle,
|
||||
SkColor lightColor, SkScalar surfaceScale, SkScalar kd,
|
||||
SkImageFilter* input = NULL, const CropRect* cropRect = NULL);
|
||||
static SkImageFilter* CreateDistantLitSpecular(const SkPoint3& direction,
|
||||
sk_sp<SkImageFilter> input, const CropRect* cropRect = nullptr);
|
||||
static sk_sp<SkImageFilter> MakeDistantLitSpecular(const SkPoint3& direction,
|
||||
SkColor lightColor, SkScalar surfaceScale, SkScalar ks,
|
||||
SkScalar shininess, SkImageFilter* input = NULL, const CropRect* cropRect = NULL);
|
||||
static SkImageFilter* CreatePointLitSpecular(const SkPoint3& location,
|
||||
SkScalar shininess, sk_sp<SkImageFilter> input, const CropRect* cropRect = nullptr);
|
||||
static sk_sp<SkImageFilter> MakePointLitSpecular(const SkPoint3& location,
|
||||
SkColor lightColor, SkScalar surfaceScale, SkScalar ks,
|
||||
SkScalar shininess, SkImageFilter* input = NULL, const CropRect* cropRect = NULL);
|
||||
static SkImageFilter* CreateSpotLitSpecular(const SkPoint3& location,
|
||||
SkScalar shininess, sk_sp<SkImageFilter> input, const CropRect* cropRect = nullptr);
|
||||
static sk_sp<SkImageFilter> MakeSpotLitSpecular(const SkPoint3& location,
|
||||
const SkPoint3& target, SkScalar specularExponent, SkScalar cutoffAngle,
|
||||
SkColor lightColor, SkScalar surfaceScale, SkScalar ks,
|
||||
SkScalar shininess, SkImageFilter* input = NULL, const CropRect* cropRect = NULL);
|
||||
~SkLightingImageFilter();
|
||||
SkScalar shininess, sk_sp<SkImageFilter> input, const CropRect* cropRect = nullptr);
|
||||
~SkLightingImageFilter() override;
|
||||
|
||||
SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_IMAGEFILTER_PTR
|
||||
static SkImageFilter* CreateDistantLitDiffuse(const SkPoint3& direction,
|
||||
SkColor lightColor, SkScalar surfaceScale, SkScalar kd,
|
||||
SkImageFilter* input = NULL, const CropRect* cropRect = NULL) {
|
||||
return MakeDistantLitDiffuse(direction, lightColor, surfaceScale, kd,
|
||||
sk_ref_sp<SkImageFilter>(input), cropRect).release();
|
||||
}
|
||||
static SkImageFilter* CreatePointLitDiffuse(const SkPoint3& location,
|
||||
SkColor lightColor, SkScalar surfaceScale, SkScalar kd,
|
||||
SkImageFilter* input = NULL, const CropRect* cropRect = NULL) {
|
||||
return MakePointLitDiffuse(location, lightColor, surfaceScale, kd,
|
||||
sk_ref_sp<SkImageFilter>(input), cropRect).release();
|
||||
}
|
||||
static SkImageFilter* CreateSpotLitDiffuse(const SkPoint3& location,
|
||||
const SkPoint3& target, SkScalar specularExponent, SkScalar cutoffAngle,
|
||||
SkColor lightColor, SkScalar surfaceScale, SkScalar kd,
|
||||
SkImageFilter* input = NULL, const CropRect* cropRect = NULL) {
|
||||
return MakeSpotLitDiffuse(location, target, specularExponent, cutoffAngle,
|
||||
lightColor, surfaceScale, kd,
|
||||
sk_ref_sp<SkImageFilter>(input), cropRect).release();
|
||||
}
|
||||
static SkImageFilter* CreateDistantLitSpecular(const SkPoint3& direction,
|
||||
SkColor lightColor, SkScalar surfaceScale, SkScalar ks,
|
||||
SkScalar shininess, SkImageFilter* input = NULL, const CropRect* cropRect = NULL) {
|
||||
return MakeDistantLitSpecular(direction, lightColor, surfaceScale, ks, shininess,
|
||||
sk_ref_sp<SkImageFilter>(input), cropRect).release();
|
||||
}
|
||||
static SkImageFilter* CreatePointLitSpecular(const SkPoint3& location,
|
||||
SkColor lightColor, SkScalar surfaceScale, SkScalar ks,
|
||||
SkScalar shininess, SkImageFilter* input = NULL, const CropRect* cropRect = NULL) {
|
||||
return MakePointLitSpecular(location, lightColor, surfaceScale, ks, shininess,
|
||||
sk_ref_sp<SkImageFilter>(input), cropRect).release();
|
||||
}
|
||||
static SkImageFilter* CreateSpotLitSpecular(const SkPoint3& location,
|
||||
const SkPoint3& target, SkScalar specularExponent, SkScalar cutoffAngle,
|
||||
SkColor lightColor, SkScalar surfaceScale, SkScalar ks,
|
||||
SkScalar shininess, SkImageFilter* input = NULL, const CropRect* cropRect = NULL) {
|
||||
return MakeSpotLitSpecular(location, target, specularExponent, cutoffAngle,
|
||||
lightColor, surfaceScale, ks, shininess,
|
||||
sk_ref_sp<SkImageFilter>(input), cropRect).release();
|
||||
}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
SkLightingImageFilter(SkImageFilterLight* light,
|
||||
SkLightingImageFilter(sk_sp<SkImageFilterLight> light,
|
||||
SkScalar surfaceScale,
|
||||
SkImageFilter* input,
|
||||
sk_sp<SkImageFilter> input,
|
||||
const CropRect* cropRect);
|
||||
void flatten(SkWriteBuffer&) const override;
|
||||
const SkImageFilterLight* light() const { return fLight.get(); }
|
||||
|
@ -52,9 +95,10 @@ protected:
|
|||
bool affectsTransparentBlack() const override { return true; }
|
||||
|
||||
private:
|
||||
typedef SkImageFilter INHERITED;
|
||||
SkAutoTUnref<SkImageFilterLight> fLight;
|
||||
sk_sp<SkImageFilterLight> fLight;
|
||||
SkScalar fSurfaceScale;
|
||||
|
||||
typedef SkImageFilter INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#define SkLumaColorFilter_DEFINED
|
||||
|
||||
#include "SkColorFilter.h"
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
/**
|
||||
* Luminance-to-alpha color filter, as defined in
|
||||
|
@ -32,7 +33,7 @@ public:
|
|||
void filterSpan(const SkPMColor src[], int count, SkPMColor[]) const override;
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
const GrFragmentProcessor* asFragmentProcessor(GrContext*) const override;
|
||||
sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*) const override;
|
||||
#endif
|
||||
|
||||
SK_TO_STRING_OVERRIDE()
|
||||
|
|
|
@ -14,7 +14,9 @@
|
|||
|
||||
class SK_API SkMagnifierImageFilter : public SkImageFilter {
|
||||
public:
|
||||
static sk_sp<SkImageFilter> Make(const SkRect& src, SkScalar inset, sk_sp<SkImageFilter> input);
|
||||
static sk_sp<SkImageFilter> Make(const SkRect& src, SkScalar inset,
|
||||
sk_sp<SkImageFilter> input,
|
||||
const CropRect* cropRect = nullptr);
|
||||
|
||||
SK_TO_STRING_OVERRIDE()
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMagnifierImageFilter)
|
||||
|
@ -27,15 +29,14 @@ public:
|
|||
#endif
|
||||
|
||||
protected:
|
||||
SkMagnifierImageFilter(const SkRect& srcRect, SkScalar inset, sk_sp<SkImageFilter> input);
|
||||
SkMagnifierImageFilter(const SkRect& srcRect,
|
||||
SkScalar inset,
|
||||
sk_sp<SkImageFilter> input,
|
||||
const CropRect* cropRect);
|
||||
void flatten(SkWriteBuffer&) const override;
|
||||
|
||||
bool onFilterImageDeprecated(Proxy*, const SkBitmap& src, const Context&,
|
||||
SkBitmap* result, SkIPoint* offset) const override;
|
||||
#if SK_SUPPORT_GPU
|
||||
bool asFragmentProcessor(GrFragmentProcessor**, GrTexture*, const SkMatrix&,
|
||||
const SkIRect& bounds) const override;
|
||||
#endif
|
||||
sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&,
|
||||
SkIPoint* offset) const override;
|
||||
|
||||
private:
|
||||
SkRect fSrcRect;
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#include "SkSize.h"
|
||||
#include "SkPoint.h"
|
||||
|
||||
class SkBitmap;
|
||||
|
||||
/*! \class SkMatrixConvolutionImageFilter
|
||||
Matrix convolution image filter. This filter applies an NxM image
|
||||
processing kernel to a given input image. This can be used to produce
|
||||
|
@ -29,7 +31,7 @@ public:
|
|||
kMax_TileMode = kClampToBlack_TileMode
|
||||
};
|
||||
|
||||
virtual ~SkMatrixConvolutionImageFilter();
|
||||
~SkMatrixConvolutionImageFilter() override;
|
||||
|
||||
/** Construct a matrix convolution image filter.
|
||||
@param kernelSize The kernel size in pixels, in each dimension (N by M).
|
||||
|
@ -52,6 +54,20 @@ public:
|
|||
passed to filterImage() is used instead.
|
||||
@param cropRect The rectangle to which the output processing will be limited.
|
||||
*/
|
||||
static sk_sp<SkImageFilter> Make(const SkISize& kernelSize,
|
||||
const SkScalar* kernel,
|
||||
SkScalar gain,
|
||||
SkScalar bias,
|
||||
const SkIPoint& kernelOffset,
|
||||
TileMode tileMode,
|
||||
bool convolveAlpha,
|
||||
sk_sp<SkImageFilter> input,
|
||||
const CropRect* cropRect = nullptr);
|
||||
|
||||
SK_TO_STRING_OVERRIDE()
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMatrixConvolutionImageFilter)
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_IMAGEFILTER_PTR
|
||||
static SkImageFilter* Create(const SkISize& kernelSize,
|
||||
const SkScalar* kernel,
|
||||
SkScalar gain,
|
||||
|
@ -60,10 +76,11 @@ public:
|
|||
TileMode tileMode,
|
||||
bool convolveAlpha,
|
||||
SkImageFilter* input = NULL,
|
||||
const CropRect* cropRect = NULL);
|
||||
|
||||
SK_TO_STRING_OVERRIDE()
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMatrixConvolutionImageFilter)
|
||||
const CropRect* cropRect = NULL) {
|
||||
return Make(kernelSize, kernel, gain, bias, kernelOffset, tileMode, convolveAlpha,
|
||||
sk_ref_sp<SkImageFilter>(input), cropRect).release();
|
||||
}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
SkMatrixConvolutionImageFilter(const SkISize& kernelSize,
|
||||
|
@ -73,20 +90,15 @@ protected:
|
|||
const SkIPoint& kernelOffset,
|
||||
TileMode tileMode,
|
||||
bool convolveAlpha,
|
||||
SkImageFilter* input,
|
||||
sk_sp<SkImageFilter> input,
|
||||
const CropRect* cropRect);
|
||||
void flatten(SkWriteBuffer&) const override;
|
||||
|
||||
bool onFilterImageDeprecated(Proxy*, const SkBitmap& src, const Context&,
|
||||
SkBitmap* result, SkIPoint* loc) const override;
|
||||
sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&,
|
||||
SkIPoint* offset) const override;
|
||||
SkIRect onFilterNodeBounds(const SkIRect&, const SkMatrix&, MapDirection) const override;
|
||||
bool affectsTransparentBlack() const override;
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
bool asFragmentProcessor(GrFragmentProcessor**, GrTexture*, const SkMatrix&,
|
||||
const SkIRect& bounds) const override;
|
||||
#endif
|
||||
|
||||
private:
|
||||
SkISize fKernelSize;
|
||||
SkScalar* fKernel;
|
||||
|
@ -95,7 +107,6 @@ private:
|
|||
SkIPoint fKernelOffset;
|
||||
TileMode fTileMode;
|
||||
bool fConvolveAlpha;
|
||||
typedef SkImageFilter INHERITED;
|
||||
|
||||
template <class PixelFetcher, bool convolveAlpha>
|
||||
void filterPixels(const SkBitmap& src,
|
||||
|
@ -115,6 +126,8 @@ private:
|
|||
SkBitmap* result,
|
||||
const SkIRect& rect,
|
||||
const SkIRect& bounds) const;
|
||||
|
||||
typedef SkImageFilter INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,18 +18,11 @@ public:
|
|||
|
||||
static sk_sp<SkImageFilter> Make(sk_sp<SkImageFilter> first, sk_sp<SkImageFilter> second,
|
||||
SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode,
|
||||
const CropRect* cropRect = nullptr) {
|
||||
sk_sp<SkImageFilter> inputs[2] = { first, second };
|
||||
SkXfermode::Mode modes[2] = { mode, mode };
|
||||
return sk_sp<SkImageFilter>(new SkMergeImageFilter(inputs, 2, modes, cropRect));
|
||||
}
|
||||
|
||||
const CropRect* cropRect = nullptr);
|
||||
static sk_sp<SkImageFilter> Make(sk_sp<SkImageFilter> filters[],
|
||||
int count,
|
||||
const SkXfermode::Mode modes[] = nullptr,
|
||||
const CropRect* cropRect = nullptr) {
|
||||
return sk_sp<SkImageFilter>(new SkMergeImageFilter(filters, count, modes, cropRect));
|
||||
}
|
||||
const CropRect* cropRect = nullptr);
|
||||
|
||||
SK_TO_STRING_OVERRIDE()
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMergeImageFilter)
|
||||
|
@ -58,6 +51,7 @@ protected:
|
|||
void flatten(SkWriteBuffer&) const override;
|
||||
sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&,
|
||||
SkIPoint* offset) const override;
|
||||
bool onCanHandleComplexCTM() const override { return true; }
|
||||
|
||||
private:
|
||||
SkMergeImageFilter(sk_sp<SkImageFilter> filters[], int count, const SkXfermode::Mode modes[],
|
||||
|
|
|
@ -57,14 +57,7 @@ class SK_API SkDilateImageFilter : public SkMorphologyImageFilter {
|
|||
public:
|
||||
static sk_sp<SkImageFilter> Make(int radiusX, int radiusY,
|
||||
sk_sp<SkImageFilter> input,
|
||||
const CropRect* cropRect = nullptr) {
|
||||
if (radiusX < 0 || radiusY < 0) {
|
||||
return nullptr;
|
||||
}
|
||||
return sk_sp<SkImageFilter>(new SkDilateImageFilter(radiusX, radiusY,
|
||||
std::move(input),
|
||||
cropRect));
|
||||
}
|
||||
const CropRect* cropRect = nullptr);
|
||||
|
||||
SK_TO_STRING_OVERRIDE()
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDilateImageFilter)
|
||||
|
@ -96,14 +89,7 @@ class SK_API SkErodeImageFilter : public SkMorphologyImageFilter {
|
|||
public:
|
||||
static sk_sp<SkImageFilter> Make(int radiusX, int radiusY,
|
||||
sk_sp<SkImageFilter> input,
|
||||
const CropRect* cropRect = nullptr) {
|
||||
if (radiusX < 0 || radiusY < 0) {
|
||||
return nullptr;
|
||||
}
|
||||
return sk_sp<SkImageFilter>(new SkErodeImageFilter(radiusX, radiusY,
|
||||
std::move(input),
|
||||
cropRect));
|
||||
}
|
||||
const CropRect* cropRect = nullptr);
|
||||
|
||||
SK_TO_STRING_OVERRIDE()
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkErodeImageFilter)
|
||||
|
|
|
@ -15,13 +15,7 @@ class SK_API SkOffsetImageFilter : public SkImageFilter {
|
|||
public:
|
||||
static sk_sp<SkImageFilter> Make(SkScalar dx, SkScalar dy,
|
||||
sk_sp<SkImageFilter> input,
|
||||
const CropRect* cropRect = nullptr) {
|
||||
if (!SkScalarIsFinite(dx) || !SkScalarIsFinite(dy)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return sk_sp<SkImageFilter>(new SkOffsetImageFilter(dx, dy, std::move(input), cropRect));
|
||||
}
|
||||
const CropRect* cropRect = nullptr);
|
||||
|
||||
SkRect computeFastBounds(const SkRect& src) const override;
|
||||
|
||||
|
|
|
@ -22,9 +22,7 @@ public:
|
|||
* not specified, the source primitive's bounds are used
|
||||
* instead.
|
||||
*/
|
||||
static sk_sp<SkImageFilter> Make(const SkPaint& paint, const CropRect* cropRect = nullptr) {
|
||||
return sk_sp<SkImageFilter>(new SkPaintImageFilter(paint, cropRect));
|
||||
}
|
||||
static sk_sp<SkImageFilter> Make(const SkPaint& paint, const CropRect* cropRect = nullptr);
|
||||
|
||||
bool affectsTransparentBlack() const override;
|
||||
|
||||
|
|
|
@ -102,8 +102,7 @@ public:
|
|||
};
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
const GrFragmentProcessor* asFragmentProcessor(GrContext* context, const SkMatrix& viewM,
|
||||
const SkMatrix*, SkFilterQuality) const override;
|
||||
sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const override;
|
||||
#endif
|
||||
|
||||
SK_TO_STRING_OVERRIDE()
|
||||
|
|
|
@ -16,20 +16,13 @@ public:
|
|||
/**
|
||||
* Refs the passed-in picture.
|
||||
*/
|
||||
static sk_sp<SkImageFilter> Make(sk_sp<SkPicture> picture) {
|
||||
return sk_sp<SkImageFilter>(new SkPictureImageFilter(std::move(picture)));
|
||||
}
|
||||
static sk_sp<SkImageFilter> Make(sk_sp<SkPicture> picture);
|
||||
|
||||
/**
|
||||
* Refs the passed-in picture. cropRect can be used to crop or expand the destination rect when
|
||||
* the picture is drawn. (No scaling is implied by the dest rect; only the CTM is applied.)
|
||||
*/
|
||||
static sk_sp<SkImageFilter> Make(sk_sp<SkPicture> picture, const SkRect& cropRect) {
|
||||
return sk_sp<SkImageFilter>(new SkPictureImageFilter(std::move(picture),
|
||||
cropRect,
|
||||
kDeviceSpace_PictureResolution,
|
||||
kLow_SkFilterQuality));
|
||||
}
|
||||
static sk_sp<SkImageFilter> Make(sk_sp<SkPicture> picture, const SkRect& cropRect);
|
||||
|
||||
/**
|
||||
* Refs the passed-in picture. The picture is rasterized at a resolution that matches the
|
||||
|
@ -40,12 +33,7 @@ public:
|
|||
*/
|
||||
static sk_sp<SkImageFilter> MakeForLocalSpace(sk_sp<SkPicture> picture,
|
||||
const SkRect& cropRect,
|
||||
SkFilterQuality filterQuality) {
|
||||
return sk_sp<SkImageFilter>(new SkPictureImageFilter(std::move(picture),
|
||||
cropRect,
|
||||
kLocalSpace_PictureResolution,
|
||||
filterQuality));
|
||||
}
|
||||
SkFilterQuality filterQuality);
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_IMAGEFILTER_PTR
|
||||
static SkImageFilter* Create(const SkPicture* picture) {
|
||||
|
@ -79,17 +67,20 @@ protected:
|
|||
* @param SkReadBuffer Serialized picture data.
|
||||
*/
|
||||
void flatten(SkWriteBuffer&) const override;
|
||||
bool onFilterImageDeprecated(Proxy*, const SkBitmap& src, const Context&, SkBitmap* result,
|
||||
SkIPoint* offset) const override;
|
||||
sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&,
|
||||
SkIPoint* offset) const override;
|
||||
|
||||
private:
|
||||
explicit SkPictureImageFilter(sk_sp<SkPicture> picture);
|
||||
SkPictureImageFilter(sk_sp<SkPicture> picture, const SkRect& cropRect,
|
||||
PictureResolution, SkFilterQuality);
|
||||
|
||||
void drawPictureAtDeviceResolution(SkBaseDevice*, const SkIRect& deviceBounds,
|
||||
void drawPictureAtDeviceResolution(SkCanvas* canvas,
|
||||
const SkIRect& deviceBounds,
|
||||
const Context&) const;
|
||||
void drawPictureAtLocalResolution(Proxy*, SkBaseDevice*, const SkIRect& deviceBounds,
|
||||
void drawPictureAtLocalResolution(SkSpecialImage* source,
|
||||
SkCanvas*,
|
||||
const SkIRect& deviceBounds,
|
||||
const Context&) const;
|
||||
|
||||
sk_sp<SkPicture> fPicture;
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkRRectsGaussianEdgeShader_DEFINED
|
||||
#define SkRRectsGaussianEdgeShader_DEFINED
|
||||
|
||||
#include "SkShader.h"
|
||||
|
||||
class SkRRect;
|
||||
|
||||
class SK_API SkRRectsGaussianEdgeShader {
|
||||
public:
|
||||
/** Returns a shader that applies a Gaussian blur depending on distance to the edge
|
||||
* of the intersection of two round rects.
|
||||
* Currently this is only useable with round rects that have the same radii at
|
||||
* all the corners and for which the x & y radii are equal.
|
||||
* Raster will draw nothing.
|
||||
*
|
||||
* The coverage geometry that should be drawn should be no larger than the intersection
|
||||
* of the bounding boxes of the two round rects. Ambitious users can omit the center
|
||||
* area of the coverage geometry if it is known to be occluded.
|
||||
*/
|
||||
static sk_sp<SkShader> Make(const SkRRect& first,
|
||||
const SkRRect& second,
|
||||
SkScalar radius, SkScalar unused = 0.0f);
|
||||
|
||||
SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
|
||||
|
||||
private:
|
||||
SkRRectsGaussianEdgeShader(); // can't be instantiated
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,52 +0,0 @@
|
|||
/*
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef _SkTestImageFilters_h
|
||||
#define _SkTestImageFilters_h
|
||||
|
||||
#include "SkImageFilter.h"
|
||||
#include "SkPoint.h"
|
||||
|
||||
// Fun mode that scales down (only) and then scales back up to look pixelated
|
||||
class SK_API SkDownSampleImageFilter : public SkImageFilter {
|
||||
public:
|
||||
static sk_sp<SkImageFilter> Make(SkScalar scale, sk_sp<SkImageFilter> input) {
|
||||
if (!SkScalarIsFinite(scale)) {
|
||||
return nullptr;
|
||||
}
|
||||
// we don't support scale in this range
|
||||
if (scale > SK_Scalar1 || scale <= 0) {
|
||||
return nullptr;
|
||||
}
|
||||
return sk_sp<SkImageFilter>(new SkDownSampleImageFilter(scale, std::move(input)));
|
||||
}
|
||||
|
||||
SK_TO_STRING_OVERRIDE()
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDownSampleImageFilter)
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_IMAGEFILTER_PTR
|
||||
static SkImageFilter* Create(SkScalar scale, SkImageFilter* input = nullptr) {
|
||||
return Make(scale, sk_ref_sp<SkImageFilter>(input)).release();
|
||||
}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
void flatten(SkWriteBuffer&) const override;
|
||||
|
||||
sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&,
|
||||
SkIPoint* offset) const override;
|
||||
|
||||
private:
|
||||
SkDownSampleImageFilter(SkScalar scale, sk_sp<SkImageFilter> input)
|
||||
: INHERITED(&input, 1, nullptr), fScale(scale) {}
|
||||
|
||||
SkScalar fScale;
|
||||
|
||||
typedef SkImageFilter INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -11,18 +11,16 @@
|
|||
#include "SkImageFilter.h"
|
||||
|
||||
class SK_API SkTileImageFilter : public SkImageFilter {
|
||||
typedef SkImageFilter INHERITED;
|
||||
|
||||
public:
|
||||
/** Create a tile image filter
|
||||
@param src Defines the pixels to tile
|
||||
@param dst Defines the pixels where tiles are drawn
|
||||
@param input Input from which the subregion defined by srcRect will be tiled
|
||||
*/
|
||||
static SkImageFilter* Create(const SkRect& src, const SkRect& dst, SkImageFilter* input);
|
||||
static sk_sp<SkImageFilter> Make(const SkRect& src,
|
||||
const SkRect& dst,
|
||||
sk_sp<SkImageFilter> input);
|
||||
|
||||
bool onFilterImageDeprecated(Proxy* proxy, const SkBitmap& src, const Context& ctx,
|
||||
SkBitmap* dst, SkIPoint* offset) const override;
|
||||
SkIRect onFilterBounds(const SkIRect& src, const SkMatrix&, MapDirection) const override;
|
||||
SkIRect onFilterNodeBounds(const SkIRect&, const SkMatrix&, MapDirection) const override;
|
||||
SkRect computeFastBounds(const SkRect& src) const override;
|
||||
|
@ -30,15 +28,26 @@ public:
|
|||
SK_TO_STRING_OVERRIDE()
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTileImageFilter)
|
||||
|
||||
#ifdef SK_SUPPORT_LEGACY_IMAGEFILTER_PTR
|
||||
static SkImageFilter* Create(const SkRect& src, const SkRect& dst, SkImageFilter* input) {
|
||||
return Make(src, dst, sk_ref_sp<SkImageFilter>(input)).release();
|
||||
}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
void flatten(SkWriteBuffer& buffer) const override;
|
||||
|
||||
sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&,
|
||||
SkIPoint* offset) const override;
|
||||
|
||||
private:
|
||||
SkTileImageFilter(const SkRect& srcRect, const SkRect& dstRect, SkImageFilter* input)
|
||||
: INHERITED(1, &input, NULL), fSrcRect(srcRect), fDstRect(dstRect) {}
|
||||
SkTileImageFilter(const SkRect& srcRect, const SkRect& dstRect, sk_sp<SkImageFilter> input)
|
||||
: INHERITED(&input, 1, nullptr), fSrcRect(srcRect), fDstRect(dstRect) {}
|
||||
|
||||
SkRect fSrcRect;
|
||||
SkRect fDstRect;
|
||||
|
||||
typedef SkImageFilter INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче