vendor: add Skia shared artifact
This commit is contained in:
parent
719abce31e
commit
d3d1643516
|
|
@ -0,0 +1,14 @@
|
|||
is_debug = false
|
||||
is_official_build = true
|
||||
is_component_build = true
|
||||
skia_enable_tools = false
|
||||
skia_use_gl = true
|
||||
skia_use_egl = true
|
||||
skia_use_vulkan = true
|
||||
skia_use_x11 = true
|
||||
skia_use_dawn = false
|
||||
skia_use_angle = false
|
||||
skia_enable_pdf = true
|
||||
skia_enable_svg = true
|
||||
skia_enable_skottie = false
|
||||
skia_build_fuzzers = false
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package(
|
||||
default_applicable_licenses = ["//:license"],
|
||||
)
|
||||
|
||||
licenses(["notice"])
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
set noparent
|
||||
|
||||
# Include one of the following reviewers for CLs that add or change Skia's public API:
|
||||
egdaniel@google.com
|
||||
fmalita@google.com
|
||||
hcm@google.com
|
||||
kjlubick@google.com
|
||||
michaelludwig@google.com
|
||||
robertphillips@google.com
|
||||
# Note: please update ../OWNERS.android when modifying this list.
|
||||
|
||||
per-file BUILD.bazel=borenet@google.com
|
||||
per-file BUILD.bazel=kjlubick@google.com
|
||||
per-file *.bzl=borenet@google.com
|
||||
per-file *.bzl=kjlubick@google.com
|
||||
per-file core/SkMilestone.h=chrome-branch-day@chops-service-accounts.iam.gserviceaccount.com
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright 2023 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
#ifndef AHardwareBufferUtils_DEFINED
|
||||
#define AHardwareBufferUtils_DEFINED
|
||||
|
||||
#include "include/core/SkColorType.h"
|
||||
#include "include/core/SkTypes.h"
|
||||
|
||||
#if __ANDROID_API__ >= 26
|
||||
|
||||
namespace AHardwareBufferUtils {
|
||||
|
||||
// SkColorType expected for AHBs imported as external images
|
||||
static const SkColorType kExternalFormatColorType = SkColorType::kRGBA_8888_SkColorType;
|
||||
|
||||
SkColorType GetSkColorTypeFromBufferFormat(uint32_t bufferFormat);
|
||||
|
||||
} // namespace AHardwareBufferUtils
|
||||
|
||||
#endif
|
||||
|
||||
#endif // AHardwareBufferUtils_DEFINED
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
load("//bazel:skia_rules.bzl", "skia_filegroup")
|
||||
|
||||
package(
|
||||
default_applicable_licenses = ["//:license"],
|
||||
)
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
skia_filegroup(
|
||||
name = "private_hdrs",
|
||||
srcs = [
|
||||
"AHardwareBufferUtils.h",
|
||||
"GrAHardwareBufferUtils.h",
|
||||
"SkCanvasAndroid.h",
|
||||
"SkImageAndroid.h",
|
||||
"SkSurfaceAndroid.h",
|
||||
],
|
||||
visibility = [
|
||||
"//src/gpu/ganesh:__pkg__",
|
||||
],
|
||||
)
|
||||
|
||||
skia_filegroup(
|
||||
name = "animated_image_hdrs",
|
||||
srcs = [
|
||||
"SkAnimatedImage.h",
|
||||
],
|
||||
visibility = ["//src/android:__pkg__"],
|
||||
)
|
||||
|
||||
skia_filegroup(
|
||||
name = "graphite_android_hdrs",
|
||||
srcs = [
|
||||
"SkSurfaceAndroid.h",
|
||||
],
|
||||
)
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Copyright 2019 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
#ifndef GrAHardwareBufferUtils_DEFINED
|
||||
#define GrAHardwareBufferUtils_DEFINED
|
||||
|
||||
#include "include/core/SkTypes.h"
|
||||
|
||||
#if defined(SK_BUILD_FOR_ANDROID) && __ANDROID_API__ >= 26
|
||||
|
||||
#include "include/gpu/ganesh/GrBackendSurface.h"
|
||||
#include "include/gpu/ganesh/GrTypes.h"
|
||||
|
||||
class GrDirectContext;
|
||||
|
||||
extern "C" {
|
||||
typedef struct AHardwareBuffer AHardwareBuffer;
|
||||
}
|
||||
|
||||
namespace GrAHardwareBufferUtils {
|
||||
|
||||
#if !defined(SK_DISABLE_LEGACY_ANDROID_HW_UTILS)
|
||||
GrBackendFormat GetBackendFormat(GrDirectContext* dContext, AHardwareBuffer* hardwareBuffer,
|
||||
uint32_t bufferFormat, bool requireKnownFormat);
|
||||
#endif
|
||||
|
||||
GrBackendFormat GetGLBackendFormat(GrDirectContext* dContext, uint32_t bufferFormat,
|
||||
bool requireKnownFormat);
|
||||
GrBackendFormat GetVulkanBackendFormat(GrDirectContext* dContext, AHardwareBuffer* hardwareBuffer,
|
||||
uint32_t bufferFormat, bool requireKnownFormat);
|
||||
|
||||
typedef void* TexImageCtx;
|
||||
typedef void (*DeleteImageProc)(TexImageCtx);
|
||||
typedef void (*UpdateImageProc)(TexImageCtx, GrDirectContext*);
|
||||
|
||||
/**
|
||||
* Create a GrBackendTexture from AHardwareBuffer
|
||||
*
|
||||
* @param context GPU context
|
||||
* @param hardwareBuffer AHB
|
||||
* @param width texture width
|
||||
* @param height texture height
|
||||
* @param deleteProc returns a function that deletes the texture and
|
||||
* other GPU resources. Must be invoked on the same
|
||||
* thread as MakeBackendTexture
|
||||
* @param updateProc returns a function, that needs to be invoked, when
|
||||
* AHB buffer content has changed. Must be invoked on
|
||||
* the same thread as MakeBackendTexture
|
||||
* @param imageCtx returns an opaque image context, that is passed as
|
||||
* first argument to deleteProc and updateProc
|
||||
* @param isProtectedContent if true, GL backend uses EXT_protected_content
|
||||
* @param backendFormat backend format, usually created with helper
|
||||
* function GetBackendFormat
|
||||
* @param isRenderable true if GrBackendTexture can be used as a color
|
||||
* attachment
|
||||
* @return valid GrBackendTexture object on success
|
||||
*/
|
||||
#if !defined(SK_DISABLE_LEGACY_ANDROID_HW_UTILS)
|
||||
GrBackendTexture MakeBackendTexture(GrDirectContext* dContext, AHardwareBuffer* hardwareBuffer,
|
||||
int width, int height,
|
||||
DeleteImageProc* deleteProc,
|
||||
UpdateImageProc* updateProc,
|
||||
TexImageCtx* imageCtx,
|
||||
bool isProtectedContent,
|
||||
const GrBackendFormat& backendFormat,
|
||||
bool isRenderable,
|
||||
bool fromAndroidWindow = false);
|
||||
#endif
|
||||
|
||||
GrBackendTexture MakeGLBackendTexture(GrDirectContext* dContext,
|
||||
AHardwareBuffer* hardwareBuffer,
|
||||
int width, int height,
|
||||
DeleteImageProc* deleteProc,
|
||||
UpdateImageProc* updateProc,
|
||||
TexImageCtx* imageCtx,
|
||||
bool isProtectedContent,
|
||||
const GrBackendFormat& backendFormat,
|
||||
bool isRenderable);
|
||||
|
||||
GrBackendTexture MakeVulkanBackendTexture(GrDirectContext* dContext,
|
||||
AHardwareBuffer* hardwareBuffer,
|
||||
int width, int height,
|
||||
DeleteImageProc* deleteProc,
|
||||
UpdateImageProc* updateProc,
|
||||
TexImageCtx* imageCtx,
|
||||
bool isProtectedContent,
|
||||
const GrBackendFormat& backendFormat,
|
||||
bool isRenderable,
|
||||
bool fromAndroidWindow = false);
|
||||
|
||||
} // namespace GrAHardwareBufferUtils
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright 2017 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkAndroidFrameworkUtils_DEFINED
|
||||
#define SkAndroidFrameworkUtils_DEFINED
|
||||
|
||||
#include "include/core/SkColor.h"
|
||||
#include "include/core/SkPoint.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/core/SkTileMode.h"
|
||||
|
||||
class SkCanvas;
|
||||
struct SkIRect;
|
||||
struct SkRect;
|
||||
class SkSurface;
|
||||
class SkShader;
|
||||
|
||||
/**
|
||||
* SkAndroidFrameworkUtils expose private APIs used only by Android framework.
|
||||
*/
|
||||
class SkAndroidFrameworkUtils {
|
||||
public:
|
||||
|
||||
#if defined(SK_GANESH)
|
||||
/**
|
||||
* clipWithStencil draws the current clip into a stencil buffer with reference value and mask
|
||||
* set to 0x1. This function works only on a GPU canvas.
|
||||
*
|
||||
* @param canvas A GPU canvas that has a non-empty clip.
|
||||
*
|
||||
* @return true on success or false if clip is empty or not a GPU canvas.
|
||||
*/
|
||||
static bool clipWithStencil(SkCanvas* canvas);
|
||||
#endif //defined(SK_GANESH)
|
||||
|
||||
static void SafetyNetLog(const char*);
|
||||
|
||||
static sk_sp<SkSurface> getSurfaceFromCanvas(SkCanvas* canvas);
|
||||
|
||||
static int SaveBehind(SkCanvas* canvas, const SkRect* subset);
|
||||
|
||||
// Operating within the canvas' clip stack, this resets the geometry of the clip to be wide
|
||||
// open modula any device clip restriction that was set outside of the clip stack.
|
||||
static void ResetClip(SkCanvas* canvas);
|
||||
|
||||
/**
|
||||
* Unrolls a chain of nested SkPaintFilterCanvas to return the base wrapped canvas.
|
||||
*
|
||||
* @param canvas A SkPaintFilterCanvas or any other SkCanvas subclass.
|
||||
*
|
||||
* @return SkCanvas that was found in the innermost SkPaintFilterCanvas.
|
||||
*/
|
||||
static SkCanvas* getBaseWrappedCanvas(SkCanvas* canvas);
|
||||
|
||||
/**
|
||||
* If the shader represents a linear gradient ShaderAsALinearGradient
|
||||
* returns true and if info is not null, ShaderAsALinearGradient populates
|
||||
* info with the parameters for the gradient. fColorCount is both an input
|
||||
* and output parameter. On input, it indicates how many entries in
|
||||
* fColors and fColorOffsets can be used, if they are not nullptr. After
|
||||
* asAGradient has run, fColorCount indicates how many color-offset pairs
|
||||
* there are in the gradient. fColorOffsets specifies where on the range of
|
||||
* 0 to 1 to transition to the given color. fPoints represent the endpoints
|
||||
* of the gradient.
|
||||
*/
|
||||
struct LinearGradientInfo {
|
||||
int fColorCount = 0; //!< In-out parameter, specifies passed size
|
||||
// of fColors/fColorOffsets on input, and
|
||||
// actual number of colors/offsets on
|
||||
// output.
|
||||
SkColor4f* fColors = nullptr; //!< The colors in the gradient.
|
||||
SkScalar* fColorOffsets = nullptr; //!< The unit offset for color transitions.
|
||||
SkPoint fPoints[2]; //!< Type specific, see above.
|
||||
SkTileMode fTileMode;
|
||||
uint32_t fGradientFlags = 0; //!< see SkGradientShader::Flags
|
||||
};
|
||||
|
||||
static bool ShaderAsALinearGradient(SkShader* shader, LinearGradientInfo*);
|
||||
};
|
||||
|
||||
#endif // SkAndroidFrameworkUtils_DEFINED
|
||||
|
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
* Copyright 2018 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkAnimatedImage_DEFINED
|
||||
#define SkAnimatedImage_DEFINED
|
||||
|
||||
#include "include/codec/SkCodecAnimation.h"
|
||||
#include "include/core/SkBitmap.h"
|
||||
#include "include/core/SkDrawable.h"
|
||||
#include "include/core/SkMatrix.h"
|
||||
#include "include/core/SkRect.h"
|
||||
|
||||
class SkAndroidCodec;
|
||||
class SkImage;
|
||||
class SkPicture;
|
||||
|
||||
/**
|
||||
* Thread unsafe drawable for drawing animated images (e.g. GIF).
|
||||
*/
|
||||
class SK_API SkAnimatedImage : public SkDrawable {
|
||||
public:
|
||||
/**
|
||||
* Create an SkAnimatedImage from the SkAndroidCodec.
|
||||
*
|
||||
* Returns null on failure to allocate pixels. On success, this will
|
||||
* decode the first frame.
|
||||
*
|
||||
* @param info Width and height may require scaling.
|
||||
* @param cropRect Rectangle to crop to after scaling.
|
||||
* @param postProcess Picture to apply after scaling and cropping.
|
||||
*/
|
||||
static sk_sp<SkAnimatedImage> Make(std::unique_ptr<SkAndroidCodec>,
|
||||
const SkImageInfo& info, SkIRect cropRect, sk_sp<SkPicture> postProcess);
|
||||
|
||||
/**
|
||||
* Simpler version that uses the default size, no cropping, and no postProcess.
|
||||
*/
|
||||
static sk_sp<SkAnimatedImage> Make(std::unique_ptr<SkAndroidCodec>);
|
||||
|
||||
~SkAnimatedImage() override;
|
||||
|
||||
/**
|
||||
* Reset the animation to the beginning.
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/**
|
||||
* Whether the animation completed.
|
||||
*
|
||||
* Returns true after all repetitions are complete, or an error stops the
|
||||
* animation. Gets reset to false if the animation is restarted.
|
||||
*/
|
||||
bool isFinished() const { return fFinished; }
|
||||
|
||||
/**
|
||||
* Returned by decodeNextFrame and currentFrameDuration if the animation
|
||||
* is not running.
|
||||
*/
|
||||
static constexpr int kFinished = -1;
|
||||
|
||||
/**
|
||||
* Decode the next frame.
|
||||
*
|
||||
* If the animation is on the last frame or has hit an error, returns
|
||||
* kFinished.
|
||||
*/
|
||||
int decodeNextFrame();
|
||||
|
||||
/**
|
||||
* Returns the current frame as an SkImage. The SkImage will not change
|
||||
* after it has been returned.
|
||||
* If there is no current frame, nullptr will be returned.
|
||||
*/
|
||||
sk_sp<SkImage> getCurrentFrame();
|
||||
|
||||
/**
|
||||
* How long to display the current frame.
|
||||
*
|
||||
* Useful for the first frame, for which decodeNextFrame is called
|
||||
* internally.
|
||||
*/
|
||||
int currentFrameDuration() {
|
||||
return fCurrentFrameDuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the repetition count.
|
||||
*
|
||||
* By default, the image will repeat the number of times indicated in the
|
||||
* encoded data.
|
||||
*
|
||||
* Use SkCodec::kRepetitionCountInfinite for infinite, and 0 to show all
|
||||
* frames once and then stop.
|
||||
*/
|
||||
void setRepetitionCount(int count);
|
||||
|
||||
/**
|
||||
* Return the currently set repetition count.
|
||||
*/
|
||||
int getRepetitionCount() const {
|
||||
return fRepetitionCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the total number of frames in the animation.
|
||||
*/
|
||||
int getFrameCount() const { return fFrameCount; }
|
||||
|
||||
/**
|
||||
* Change the filter mode.
|
||||
*
|
||||
* By default, the image will apply bilinear filtering when drawing in the
|
||||
* OnDraw method.
|
||||
*/
|
||||
void setFilterMode(SkFilterMode filterMode);
|
||||
|
||||
/**
|
||||
* Return the filter mode used for sampling when drawing.
|
||||
*/
|
||||
SkFilterMode getFilterMode() const { return fFilterMode; }
|
||||
|
||||
protected:
|
||||
SkRect onGetBounds() override;
|
||||
void onDraw(SkCanvas*) override;
|
||||
|
||||
private:
|
||||
struct Frame {
|
||||
SkBitmap fBitmap;
|
||||
int fIndex;
|
||||
SkCodecAnimation::DisposalMethod fDisposalMethod;
|
||||
|
||||
// init() may have to create a new SkPixelRef, if the
|
||||
// current one is already in use by another owner (e.g.
|
||||
// an SkPicture). This determines whether to copy the
|
||||
// existing one to the new one.
|
||||
enum class OnInit {
|
||||
// Restore the image from the old SkPixelRef to the
|
||||
// new one.
|
||||
kRestoreIfNecessary,
|
||||
// No need to restore.
|
||||
kNoRestore,
|
||||
};
|
||||
|
||||
Frame();
|
||||
bool init(const SkImageInfo& info, OnInit);
|
||||
bool copyTo(Frame*) const;
|
||||
};
|
||||
|
||||
std::unique_ptr<SkAndroidCodec> fCodec;
|
||||
SkImageInfo fDecodeInfo;
|
||||
const SkIRect fCropRect;
|
||||
const sk_sp<SkPicture> fPostProcess;
|
||||
const int fFrameCount;
|
||||
SkMatrix fMatrix;
|
||||
int fSampleSize;
|
||||
|
||||
bool fFinished;
|
||||
int fCurrentFrameDuration;
|
||||
Frame fDisplayFrame;
|
||||
Frame fDecodingFrame;
|
||||
Frame fRestoreFrame;
|
||||
int fRepetitionCount;
|
||||
int fRepetitionsCompleted;
|
||||
SkFilterMode fFilterMode = SkFilterMode::kLinear;
|
||||
|
||||
SkAnimatedImage(std::unique_ptr<SkAndroidCodec>, const SkImageInfo& requestedInfo,
|
||||
SkIRect cropRect, sk_sp<SkPicture> postProcess);
|
||||
|
||||
int computeNextFrame(int current, bool* animationEnded);
|
||||
double finish();
|
||||
|
||||
/**
|
||||
* True if there is no crop, orientation, or post decoding scaling.
|
||||
*/
|
||||
bool simple() const { return fMatrix.isIdentity() && !fPostProcess
|
||||
&& fCropRect == fDecodeInfo.bounds(); }
|
||||
|
||||
/**
|
||||
* Returns the current frame as an SkImage.
|
||||
*
|
||||
* Like getCurrentFrame, but only returns the raw data from the internal SkBitmap. (i.e. no
|
||||
* scaling, orientation-correction or cropping.) If simple(), this is the final output.
|
||||
*/
|
||||
sk_sp<SkImage> getCurrentFrameSimple();
|
||||
|
||||
using INHERITED = SkDrawable;
|
||||
};
|
||||
|
||||
#endif // SkAnimatedImage_DEFINED
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright 2023 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkCanvasAndroid_DEFINED
|
||||
#define SkCanvasAndroid_DEFINED
|
||||
|
||||
class SkCanvas;
|
||||
struct SkIRect;
|
||||
class GrBackendRenderTarget;
|
||||
|
||||
namespace skgpu::ganesh {
|
||||
SkIRect TopLayerBounds(const SkCanvas*);
|
||||
GrBackendRenderTarget TopLayerBackendRenderTarget(const SkCanvas*);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Copyright 2023 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkImageAndroid_DEFINED
|
||||
#define SkImageAndroid_DEFINED
|
||||
|
||||
#include "include/core/SkImage.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/gpu/ganesh/GrTypes.h"
|
||||
|
||||
class SkColorSpace;
|
||||
class GrDirectContext;
|
||||
class GrRecordingContext;
|
||||
class SkPixmap;
|
||||
struct AHardwareBuffer;
|
||||
|
||||
namespace SkImages {
|
||||
|
||||
/** (See skbug.com/40038695)
|
||||
Creates SkImage from Android hardware buffer.
|
||||
Returned SkImage takes a reference on the buffer.
|
||||
Only available on Android, when __ANDROID_API__ is defined to be 26 or greater.
|
||||
@param hardwareBuffer AHardwareBuffer Android hardware buffer
|
||||
@param colorSpace range of colors; may be nullptr
|
||||
@return created SkImage, or nullptr
|
||||
*/
|
||||
SK_API sk_sp<SkImage> DeferredFromAHardwareBuffer(AHardwareBuffer* hardwareBuffer,
|
||||
SkAlphaType alphaType = kPremul_SkAlphaType);
|
||||
SK_API sk_sp<SkImage> DeferredFromAHardwareBuffer(
|
||||
AHardwareBuffer* hardwareBuffer,
|
||||
SkAlphaType alphaType,
|
||||
sk_sp<SkColorSpace> colorSpace,
|
||||
GrSurfaceOrigin surfaceOrigin = kTopLeft_GrSurfaceOrigin);
|
||||
|
||||
/** Creates SkImage from Android hardware buffer and uploads the data from the SkPixmap to it.
|
||||
Returned SkImage takes a reference on the buffer.
|
||||
Only available on Android, when __ANDROID_API__ is defined to be 26 or greater.
|
||||
@param context GPU context
|
||||
@param pixmap SkPixmap that contains data to be uploaded to the AHardwareBuffer
|
||||
@param hardwareBuffer AHardwareBuffer Android hardware buffer
|
||||
@param surfaceOrigin surface origin for resulting image
|
||||
@return created SkImage, or nullptr
|
||||
*/
|
||||
SK_API sk_sp<SkImage> TextureFromAHardwareBufferWithData(
|
||||
GrDirectContext* context,
|
||||
const SkPixmap& pixmap,
|
||||
AHardwareBuffer* hardwareBuffer,
|
||||
GrSurfaceOrigin surfaceOrigin = kTopLeft_GrSurfaceOrigin);
|
||||
|
||||
/**
|
||||
* Like SkImage::MakeFromBitmap, except this can be pinned using
|
||||
* skgpu::ganesh::PinAsTexture and Skia will *not* copy the bitmap.
|
||||
*/
|
||||
SK_API sk_sp<SkImage> PinnableRasterFromBitmap(const SkBitmap&);
|
||||
|
||||
/**
|
||||
* Like SkImage::MakeFromBitmap, except and Skia will *not* copy the bitmap.
|
||||
*/
|
||||
SK_API sk_sp<SkImage> RasterFromBitmapNoCopy(const SkBitmap&);
|
||||
|
||||
} // namespace SkImages
|
||||
|
||||
namespace skgpu::ganesh {
|
||||
/**
|
||||
* Will attempt to upload and lock the contents of the image as a texture, so that subsequent
|
||||
* draws to a gpu-target will come from that texture (and not by looking at the original image
|
||||
* src). In particular this is intended to use the texture even if the image's original content
|
||||
* changes subsequent to this call (i.e. the src is mutable!).
|
||||
*
|
||||
* Only compatible with SkImages created from SkImages::PinnableRasterFromBitmap.
|
||||
*
|
||||
* All successful calls must be balanced by an equal number of calls to UnpinTexture().
|
||||
*
|
||||
* Once in this "pinned" state, the image has all of the same thread restrictions that exist
|
||||
* for a natively created gpu image (e.g. SkImage::MakeFromTexture)
|
||||
* - all drawing, pinning, unpinning must happen in the same thread as the GrContext.
|
||||
*
|
||||
* @return true if the image was successfully uploaded and locked into a texture
|
||||
*/
|
||||
bool PinAsTexture(GrRecordingContext*, SkImage*);
|
||||
|
||||
/**
|
||||
* The balancing call to a successful invocation of PinAsTexture. When a balanced
|
||||
* number of calls have been made, then the "pinned" texture is free to be purged, etc. This
|
||||
* also means that a subsequent "pin" call will look at the original content again, and if
|
||||
* its uniqueID/generationID has changed, then a newer texture will be uploaded/pinned.
|
||||
*
|
||||
* Only compatible with SkImages created from SkImages::PinnableRasterFromBitmap.
|
||||
*
|
||||
* The context passed to unpin must match the one passed to pin.
|
||||
*/
|
||||
void UnpinTexture(GrRecordingContext*, SkImage*);
|
||||
|
||||
} // namespace skgpu::ganesh
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright 2023 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkSurfaceAndroid_DEFINED
|
||||
#define SkSurfaceAndroid_DEFINED
|
||||
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/core/SkSurface.h"
|
||||
#include "include/gpu/ganesh/GrTypes.h"
|
||||
|
||||
class SkColorSpace;
|
||||
class GrDirectContext;
|
||||
class SkPixmap;
|
||||
struct AHardwareBuffer;
|
||||
|
||||
namespace SkSurfaces {
|
||||
|
||||
/** Private; only to be used by Android Framework.
|
||||
Creates SkSurface from Android hardware buffer.
|
||||
Returned SkSurface takes a reference on the buffer. The ref on the buffer will be released
|
||||
when the SkSurface is destroyed and there is no pending work on the GPU involving the
|
||||
buffer.
|
||||
|
||||
Currently this is only supported for buffers that can be textured as well as rendered to.
|
||||
In other words that must have both AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT and
|
||||
AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE usage bits.
|
||||
|
||||
@param context GPU context
|
||||
@param hardwareBuffer AHardwareBuffer Android hardware buffer
|
||||
@param colorSpace range of colors; may be nullptr
|
||||
@param surfaceProps LCD striping orientation and setting for device independent
|
||||
fonts; may be nullptr
|
||||
@param fromWindow Whether or not the AHardwareBuffer is part of an Android Window.
|
||||
Currently only used with Vulkan backend.
|
||||
@return created SkSurface, or nullptr
|
||||
*/
|
||||
SK_API sk_sp<SkSurface> WrapAndroidHardwareBuffer(GrDirectContext* context,
|
||||
AHardwareBuffer* hardwareBuffer,
|
||||
GrSurfaceOrigin origin,
|
||||
sk_sp<SkColorSpace> colorSpace,
|
||||
const SkSurfaceProps* surfaceProps,
|
||||
bool fromWindow = false);
|
||||
|
||||
} // namespace SkSurfaces
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright 2023 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SurfaceAndroid_DEFINED
|
||||
#define SurfaceAndroid_DEFINED
|
||||
|
||||
#include "include/core/SkRefCnt.h"
|
||||
|
||||
struct AHardwareBuffer;
|
||||
class SkColorSpace;
|
||||
class SkSurface;
|
||||
class SkSurfaceProps;
|
||||
|
||||
namespace skgpu::graphite {
|
||||
class Recorder;
|
||||
}
|
||||
|
||||
namespace SkSurfaces {
|
||||
|
||||
using ReleaseContext = void*;
|
||||
using BufferReleaseProc = void (*)(ReleaseContext);
|
||||
|
||||
/** Private; only to be used by Android Framework.
|
||||
Creates an SkSurface from an Android hardware buffer.
|
||||
|
||||
Upon success bufferReleaseProc is called when it is safe to delete the buffer in the
|
||||
backend API (accounting only for use of the buffer by this surface). If SkSurface creation
|
||||
fails bufferReleaseProc is called before this function returns.
|
||||
|
||||
Currently this is only supported for buffers that can be textured as well as rendered to.
|
||||
In other words the buffer must have both AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT and
|
||||
AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE usage bits.
|
||||
|
||||
@param recorder the applicable Graphite recorder
|
||||
@param hardwareBuffer an Android hardware buffer
|
||||
@param colorSpace range of colors; may be nullptr
|
||||
@param surfaceProps LCD striping orientation and setting for device independent
|
||||
fonts; may be nullptr
|
||||
@param bufferReleaseProc function called when the buffer can be released
|
||||
@param ReleaseContext state passed to bufferReleaseProc
|
||||
@param fromWindow Whether or not the AHardwareBuffer is part of an Android Window.
|
||||
Currently only used with Vulkan backend.
|
||||
@return created SkSurface, or nullptr
|
||||
*/
|
||||
SK_API sk_sp<SkSurface> WrapAndroidHardwareBuffer(skgpu::graphite::Recorder* recorder,
|
||||
AHardwareBuffer* hardwareBuffer,
|
||||
sk_sp<SkColorSpace> colorSpace,
|
||||
const SkSurfaceProps* surfaceProps,
|
||||
BufferReleaseProc = nullptr,
|
||||
ReleaseContext = nullptr,
|
||||
bool fromWindow = false);
|
||||
|
||||
} // namespace SkSurfaces
|
||||
|
||||
#endif // SurfaceAndroid_DEFINED
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright 2026 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef AndroidVulkanMemoryAllocator_DEFINED
|
||||
#define AndroidVulkanMemoryAllocator_DEFINED
|
||||
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/private/base/SkAPI.h"
|
||||
|
||||
namespace skgpu {
|
||||
struct VulkanBackendContext;
|
||||
class VulkanMemoryAllocator;
|
||||
}
|
||||
|
||||
namespace SkiaVMA {
|
||||
|
||||
struct Options {
|
||||
bool fThreadSafe = true;
|
||||
};
|
||||
|
||||
// Returns a concrete implementation of a memory allocator using some hard-coded settings.
|
||||
// If Android Framework ever wants to make their own, they can stop using this.
|
||||
sk_sp<skgpu::VulkanMemoryAllocator> Make(const skgpu::VulkanBackendContext&, Options);
|
||||
|
||||
} // namespace SkiaVMA
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
load("//bazel:skia_rules.bzl", "generate_cpp_files_for_headers", "skia_filegroup")
|
||||
|
||||
package(
|
||||
default_applicable_licenses = ["//:license"],
|
||||
)
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
CORE_HDRS = ["SkEncodedOrigin.h"]
|
||||
|
||||
skia_filegroup(
|
||||
name = "core_hdrs",
|
||||
srcs = CORE_HDRS,
|
||||
visibility = ["//src/core:__pkg__"],
|
||||
)
|
||||
|
||||
ANY_CODEC_HDRS = [
|
||||
"SkCodec.h",
|
||||
"SkCodecAnimation.h",
|
||||
"SkEncodedImageFormat.h",
|
||||
"SkPixmapUtils.h",
|
||||
]
|
||||
|
||||
skia_filegroup(
|
||||
name = "any_codec_hdrs",
|
||||
srcs = ANY_CODEC_HDRS,
|
||||
visibility = ["//src/codec:__pkg__"],
|
||||
)
|
||||
|
||||
ANDROID_PUBLIC_HDRS = ["SkAndroidCodec.h"]
|
||||
|
||||
skia_filegroup(
|
||||
name = "android_public_hdrs",
|
||||
srcs = ANDROID_PUBLIC_HDRS,
|
||||
visibility = ["//src/codec:__pkg__"],
|
||||
)
|
||||
|
||||
BMP_PUBLIC_HDRS = ["SkBmpDecoder.h"]
|
||||
|
||||
skia_filegroup(
|
||||
name = "bmp_public_hdrs",
|
||||
srcs = BMP_PUBLIC_HDRS,
|
||||
visibility = ["//src/codec:__pkg__"],
|
||||
)
|
||||
|
||||
GIF_PUBLIC_HDRS = ["SkGifDecoder.h"]
|
||||
|
||||
skia_filegroup(
|
||||
name = "gif_public_hdrs",
|
||||
srcs = GIF_PUBLIC_HDRS,
|
||||
visibility = ["//src/codec:__pkg__"],
|
||||
)
|
||||
|
||||
ICO_PUBLIC_HDRS = ["SkIcoDecoder.h"]
|
||||
|
||||
skia_filegroup(
|
||||
name = "ico_public_hdrs",
|
||||
srcs = ICO_PUBLIC_HDRS,
|
||||
visibility = ["//src/codec:__pkg__"],
|
||||
)
|
||||
|
||||
JPEG_PUBLIC_HDRS = ["SkJpegDecoder.h"]
|
||||
|
||||
skia_filegroup(
|
||||
name = "jpeg_public_hdrs",
|
||||
srcs = JPEG_PUBLIC_HDRS,
|
||||
visibility = ["//src/codec:__pkg__"],
|
||||
)
|
||||
|
||||
JPEGXL_PUBLIC_HDRS = ["SkJpegxlDecoder.h"]
|
||||
|
||||
skia_filegroup(
|
||||
name = "jpegxl_public_hdrs",
|
||||
srcs = JPEGXL_PUBLIC_HDRS,
|
||||
visibility = ["//src/codec:__pkg__"],
|
||||
)
|
||||
|
||||
PNG_PUBLIC_HDRS = [
|
||||
"SkPngChunkReader.h",
|
||||
"SkPngDecoder.h",
|
||||
]
|
||||
|
||||
skia_filegroup(
|
||||
name = "libpng_public_hdrs",
|
||||
srcs = PNG_PUBLIC_HDRS,
|
||||
visibility = ["//src/codec:__pkg__"],
|
||||
)
|
||||
|
||||
skia_filegroup(
|
||||
name = "rust_png_public_hdrs",
|
||||
srcs = ["SkPngRustDecoder.h"],
|
||||
visibility = ["//src/codec:__pkg__"],
|
||||
)
|
||||
|
||||
WBMP_PUBLIC_HDRS = ["SkWbmpDecoder.h"]
|
||||
|
||||
skia_filegroup(
|
||||
name = "wbmp_public_hdrs",
|
||||
srcs = WBMP_PUBLIC_HDRS,
|
||||
visibility = ["//src/codec:__pkg__"],
|
||||
)
|
||||
|
||||
WEBP_PUBLIC_HDRS = ["SkWebpDecoder.h"]
|
||||
|
||||
skia_filegroup(
|
||||
name = "webp_public_hdrs",
|
||||
srcs = WEBP_PUBLIC_HDRS,
|
||||
visibility = ["//src/codec:__pkg__"],
|
||||
)
|
||||
|
||||
generate_cpp_files_for_headers(
|
||||
name = "headers_to_compile",
|
||||
headers = CORE_HDRS +
|
||||
ANY_CODEC_HDRS +
|
||||
ANDROID_PUBLIC_HDRS +
|
||||
BMP_PUBLIC_HDRS +
|
||||
GIF_PUBLIC_HDRS +
|
||||
ICO_PUBLIC_HDRS +
|
||||
JPEG_PUBLIC_HDRS +
|
||||
JPEGXL_PUBLIC_HDRS +
|
||||
PNG_PUBLIC_HDRS +
|
||||
WBMP_PUBLIC_HDRS +
|
||||
WEBP_PUBLIC_HDRS,
|
||||
)
|
||||
|
|
@ -0,0 +1,302 @@
|
|||
/*
|
||||
* 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 SkAndroidCodec_DEFINED
|
||||
#define SkAndroidCodec_DEFINED
|
||||
|
||||
#include "include/codec/SkCodec.h"
|
||||
#include "include/core/SkColorSpace.h"
|
||||
#include "include/core/SkImageInfo.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/core/SkSize.h"
|
||||
#include "include/core/SkTypes.h"
|
||||
#include "include/private/SkEncodedInfo.h"
|
||||
#include "include/private/base/SkNoncopyable.h"
|
||||
#include "modules/skcms/skcms.h"
|
||||
|
||||
// TODO(kjlubick, bungeman) Replace these includes with forward declares
|
||||
#include "include/codec/SkEncodedImageFormat.h" // IWYU pragma: keep
|
||||
#include "include/core/SkAlphaType.h" // IWYU pragma: keep
|
||||
#include "include/core/SkColorType.h" // IWYU pragma: keep
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
|
||||
class SkData;
|
||||
class SkPngChunkReader;
|
||||
class SkStream;
|
||||
struct SkGainmapInfo;
|
||||
struct SkIRect;
|
||||
|
||||
/**
|
||||
* Abstract interface defining image codec functionality that is necessary for
|
||||
* Android.
|
||||
*/
|
||||
class SK_API SkAndroidCodec : SkNoncopyable {
|
||||
public:
|
||||
/**
|
||||
* Deprecated.
|
||||
*
|
||||
* Now that SkAndroidCodec supports multiframe images, there are multiple
|
||||
* ways to handle compositing an oriented frame on top of an oriented frame
|
||||
* with different tradeoffs. SkAndroidCodec now ignores the orientation and
|
||||
* forces the client to handle it.
|
||||
*/
|
||||
enum class ExifOrientationBehavior {
|
||||
kIgnore,
|
||||
kRespect,
|
||||
};
|
||||
|
||||
/**
|
||||
* Pass ownership of an SkCodec to a newly-created SkAndroidCodec.
|
||||
*/
|
||||
static std::unique_ptr<SkAndroidCodec> MakeFromCodec(std::unique_ptr<SkCodec>);
|
||||
|
||||
/**
|
||||
* If this stream represents an encoded image that we know how to decode,
|
||||
* return an SkAndroidCodec that can decode it. Otherwise return NULL.
|
||||
*
|
||||
* The SkPngChunkReader handles unknown chunks in PNGs.
|
||||
* See SkCodec.h for more details.
|
||||
*
|
||||
* If NULL is returned, the stream is deleted immediately. Otherwise, the
|
||||
* SkCodec takes ownership of it, and will delete it when done with it.
|
||||
*/
|
||||
static std::unique_ptr<SkAndroidCodec> MakeFromStream(std::unique_ptr<SkStream>,
|
||||
SkPngChunkReader* = nullptr);
|
||||
|
||||
/**
|
||||
* If this data represents an encoded image that we know how to decode,
|
||||
* return an SkAndroidCodec that can decode it. Otherwise return NULL.
|
||||
*
|
||||
* The SkPngChunkReader handles unknown chunks in PNGs.
|
||||
* See SkCodec.h for more details.
|
||||
*/
|
||||
static std::unique_ptr<SkAndroidCodec> MakeFromData(sk_sp<const SkData>,
|
||||
SkPngChunkReader* = nullptr);
|
||||
|
||||
virtual ~SkAndroidCodec();
|
||||
|
||||
// TODO: fInfo is now just a cache of SkCodec's SkImageInfo. No need to
|
||||
// cache and return a reference here, once Android call-sites are updated.
|
||||
const SkImageInfo& getInfo() const { return fInfo; }
|
||||
|
||||
/**
|
||||
* Return the ICC profile of the encoded data.
|
||||
*/
|
||||
const skcms_ICCProfile* getICCProfile() const {
|
||||
return fCodec->getEncodedInfo().profile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Format of the encoded data.
|
||||
*/
|
||||
SkEncodedImageFormat getEncodedFormat() const { return fCodec->getEncodedFormat(); }
|
||||
|
||||
/**
|
||||
* @param requestedColorType Color type requested by the client
|
||||
*
|
||||
* |requestedColorType| may be overriden. We will default to kF16
|
||||
* for high precision images.
|
||||
*
|
||||
* In the general case, if it is possible to decode to
|
||||
* |requestedColorType|, this returns |requestedColorType|.
|
||||
* Otherwise, this returns a color type that is an appropriate
|
||||
* match for the the encoded data.
|
||||
*/
|
||||
SkColorType computeOutputColorType(SkColorType requestedColorType);
|
||||
|
||||
/**
|
||||
* @param requestedUnpremul Indicates if the client requested
|
||||
* unpremultiplied output
|
||||
*
|
||||
* Returns the appropriate alpha type to decode to. If the image
|
||||
* has alpha, the value of requestedUnpremul will be honored.
|
||||
*/
|
||||
SkAlphaType computeOutputAlphaType(bool requestedUnpremul);
|
||||
|
||||
/**
|
||||
* @param outputColorType Color type that the client will decode to.
|
||||
* @param prefColorSpace Preferred color space to decode to.
|
||||
* This may not return |prefColorSpace| for
|
||||
* specific color types.
|
||||
*
|
||||
* Returns the appropriate color space to decode to.
|
||||
*/
|
||||
sk_sp<SkColorSpace> computeOutputColorSpace(SkColorType outputColorType,
|
||||
sk_sp<SkColorSpace> prefColorSpace = nullptr);
|
||||
|
||||
/**
|
||||
* Compute the appropriate sample size to get to |size|.
|
||||
*
|
||||
* @param size As an input parameter, the desired output size of
|
||||
* the decode. As an output parameter, the smallest sampled size
|
||||
* larger than the input.
|
||||
* @return the sample size to set AndroidOptions::fSampleSize to decode
|
||||
* to the output |size|.
|
||||
*/
|
||||
int computeSampleSize(SkISize* size) const;
|
||||
|
||||
/**
|
||||
* Returns the dimensions of the scaled output image, for an input
|
||||
* sampleSize.
|
||||
*
|
||||
* When the sample size divides evenly into the original dimensions, the
|
||||
* scaled output dimensions will simply be equal to the original
|
||||
* dimensions divided by the sample size.
|
||||
*
|
||||
* When the sample size does not divide even into the original
|
||||
* dimensions, the codec may round up or down, depending on what is most
|
||||
* efficient to decode.
|
||||
*
|
||||
* Finally, the codec will always recommend a non-zero output, so the output
|
||||
* dimension will always be one if the sampleSize is greater than the
|
||||
* original dimension.
|
||||
*/
|
||||
SkISize getSampledDimensions(int sampleSize) const;
|
||||
|
||||
/**
|
||||
* Return (via desiredSubset) a subset which can decoded from this codec,
|
||||
* or false if the input subset is invalid.
|
||||
*
|
||||
* @param desiredSubset in/out parameter
|
||||
* As input, a desired subset of the original bounds
|
||||
* (as specified by getInfo).
|
||||
* As output, if true is returned, desiredSubset may
|
||||
* have been modified to a subset which is
|
||||
* supported. Although a particular change may have
|
||||
* been made to desiredSubset to create something
|
||||
* supported, it is possible other changes could
|
||||
* result in a valid subset. If false is returned,
|
||||
* desiredSubset's value is undefined.
|
||||
* @return true If the input desiredSubset is valid.
|
||||
* desiredSubset may be modified to a subset
|
||||
* supported by the codec.
|
||||
* false If desiredSubset is invalid (NULL or not fully
|
||||
* contained within the image).
|
||||
*/
|
||||
bool getSupportedSubset(SkIRect* desiredSubset) const;
|
||||
// TODO: Rename SkCodec::getValidSubset() to getSupportedSubset()
|
||||
|
||||
/**
|
||||
* Returns the dimensions of the scaled, partial output image, for an
|
||||
* input sampleSize and subset.
|
||||
*
|
||||
* @param sampleSize Factor to scale down by.
|
||||
* @param subset Must be a valid subset of the original image
|
||||
* dimensions and a subset supported by SkAndroidCodec.
|
||||
* getSubset() can be used to obtain a subset supported
|
||||
* by SkAndroidCodec.
|
||||
* @return Size of the scaled partial image. Or zero size
|
||||
* if either of the inputs is invalid.
|
||||
*/
|
||||
SkISize getSampledSubsetDimensions(int sampleSize, const SkIRect& subset) const;
|
||||
|
||||
/**
|
||||
* Additional options to pass to getAndroidPixels().
|
||||
*/
|
||||
// FIXME: It's a bit redundant to name these AndroidOptions when this class is already
|
||||
// called SkAndroidCodec. On the other hand, it's may be a bit confusing to call
|
||||
// these Options when SkCodec has a slightly different set of Options. Maybe these
|
||||
// should be DecodeOptions or SamplingOptions?
|
||||
struct AndroidOptions : public SkCodec::Options {
|
||||
AndroidOptions()
|
||||
: SkCodec::Options()
|
||||
, fSampleSize(1)
|
||||
{}
|
||||
|
||||
/**
|
||||
* The client may provide an integer downscale factor for the decode.
|
||||
* The codec may implement this downscaling by sampling or another
|
||||
* method if it is more efficient.
|
||||
*
|
||||
* The default is 1, representing no downscaling.
|
||||
*/
|
||||
int fSampleSize;
|
||||
};
|
||||
|
||||
/**
|
||||
* Decode into the given pixels, a block of memory of size at
|
||||
* least (info.fHeight - 1) * rowBytes + (info.fWidth *
|
||||
* bytesPerPixel)
|
||||
*
|
||||
* Repeated calls to this function should give the same results,
|
||||
* allowing the PixelRef to be immutable.
|
||||
*
|
||||
* @param info A description of the format (config, size)
|
||||
* expected by the caller. This can simply be identical
|
||||
* to the info returned by getInfo().
|
||||
*
|
||||
* This contract also allows the caller to specify
|
||||
* different output-configs, which the implementation can
|
||||
* decide to support or not.
|
||||
*
|
||||
* A size that does not match getInfo() implies a request
|
||||
* to scale or subset. If the codec cannot perform this
|
||||
* scaling or subsetting, it will return an error code.
|
||||
*
|
||||
* The AndroidOptions object is also used to specify any requested scaling or subsetting
|
||||
* using options->fSampleSize and options->fSubset. If NULL, the defaults (as specified above
|
||||
* for AndroidOptions) are used.
|
||||
*
|
||||
* @return Result kSuccess, or another value explaining the type of failure.
|
||||
*/
|
||||
// FIXME: It's a bit redundant to name this getAndroidPixels() when this class is already
|
||||
// called SkAndroidCodec. On the other hand, it's may be a bit confusing to call
|
||||
// this getPixels() when it is a slightly different API than SkCodec's getPixels().
|
||||
// Maybe this should be decode() or decodeSubset()?
|
||||
SkCodec::Result getAndroidPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
|
||||
const AndroidOptions* options);
|
||||
|
||||
/**
|
||||
* Simplified version of getAndroidPixels() where we supply the default AndroidOptions as
|
||||
* specified above for AndroidOptions. It will not perform any scaling or subsetting.
|
||||
*/
|
||||
SkCodec::Result getAndroidPixels(const SkImageInfo& info, void* pixels, size_t rowBytes);
|
||||
|
||||
SkCodec::Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) {
|
||||
return this->getAndroidPixels(info, pixels, rowBytes);
|
||||
}
|
||||
|
||||
SkCodec* codec() const { return fCodec.get(); }
|
||||
|
||||
/**
|
||||
* Retrieve the gainmap codec for an image.
|
||||
*
|
||||
* @param outInfo On success, this is populated with the parameters for
|
||||
* rendering this gainmap. This parameter must be non-nullptr.
|
||||
*
|
||||
* @param outGainmapCodec On success, this is populated with a codec from which the
|
||||
* gainmap image may be decoded. This parameter is optional, and
|
||||
* may be set to nullptr.
|
||||
*
|
||||
* @return If this has a gainmap image and that gainmap image was
|
||||
* successfully extracted then return true. Otherwise return
|
||||
* false.
|
||||
*/
|
||||
bool getGainmapAndroidCodec(SkGainmapInfo* outInfo, std::unique_ptr<SkAndroidCodec>* outCodec);
|
||||
|
||||
// TODO(issues.skia.org/363544350): This API only works for JPEG images. Remove this API once
|
||||
// it is no longer used.
|
||||
bool getAndroidGainmap(SkGainmapInfo* outInfo,
|
||||
std::unique_ptr<SkStream>* outGainmapImageStream);
|
||||
|
||||
protected:
|
||||
explicit SkAndroidCodec(SkCodec*);
|
||||
|
||||
virtual SkISize onGetSampledDimensions(int sampleSize) const = 0;
|
||||
|
||||
virtual bool onGetSupportedSubset(SkIRect* desiredSubset) const = 0;
|
||||
|
||||
virtual SkCodec::Result onGetAndroidPixels(const SkImageInfo& info, void* pixels,
|
||||
size_t rowBytes, const AndroidOptions& options) = 0;
|
||||
|
||||
private:
|
||||
const SkImageInfo fInfo;
|
||||
std::unique_ptr<SkCodec> fCodec;
|
||||
};
|
||||
#endif // SkAndroidCodec_DEFINED
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright 2023 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
#ifndef SkAvifDecoder_DEFINED
|
||||
#define SkAvifDecoder_DEFINED
|
||||
|
||||
#include "include/codec/SkCodec.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/private/base/SkAPI.h"
|
||||
|
||||
class SkData;
|
||||
class SkStream;
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace SkAvifDecoder {
|
||||
|
||||
namespace LibAvif {
|
||||
|
||||
/** Returns true if this data claims to be an AVIF image. */
|
||||
SK_API bool IsAvif(const void*, size_t);
|
||||
|
||||
/**
|
||||
* Attempts to decode the given bytes as an AVIF.
|
||||
*
|
||||
* If the bytes are not an AVIF, returns nullptr.
|
||||
*
|
||||
* DecodeContext is ignored
|
||||
*/
|
||||
SK_API std::unique_ptr<SkCodec> Decode(std::unique_ptr<SkStream>,
|
||||
SkCodec::Result*,
|
||||
SkCodecs::DecodeContext = nullptr);
|
||||
SK_API std::unique_ptr<SkCodec> Decode(sk_sp<const SkData>,
|
||||
SkCodec::Result*,
|
||||
SkCodecs::DecodeContext = nullptr);
|
||||
|
||||
inline constexpr SkCodecs::Decoder Decoder() {
|
||||
return { "avif", IsAvif, Decode };
|
||||
}
|
||||
|
||||
} // namespace LibAvif
|
||||
|
||||
// This function is in the root SkAvifDecoder namespace. It simply routes
|
||||
// everything through the LibAvif namespace and exists for backwards
|
||||
// compatibility.
|
||||
inline constexpr SkCodecs::Decoder Decoder() {
|
||||
return { "avif", LibAvif::IsAvif, LibAvif::Decode };
|
||||
}
|
||||
|
||||
namespace CrabbyAvif {
|
||||
|
||||
/** Returns true if this data claims to be an AVIF image. */
|
||||
SK_API bool IsAvif(const void*, size_t);
|
||||
|
||||
/**
|
||||
* Attempts to decode the given bytes as an AVIF.
|
||||
*
|
||||
* If the bytes are not an AVIF, returns nullptr.
|
||||
*
|
||||
* DecodeContext is ignored
|
||||
*/
|
||||
SK_API std::unique_ptr<SkCodec> Decode(std::unique_ptr<SkStream>,
|
||||
SkCodec::Result*,
|
||||
SkCodecs::DecodeContext = nullptr);
|
||||
SK_API std::unique_ptr<SkCodec> Decode(sk_sp<const SkData>,
|
||||
SkCodec::Result*,
|
||||
SkCodecs::DecodeContext = nullptr);
|
||||
|
||||
inline constexpr SkCodecs::Decoder Decoder() {
|
||||
return { "avif", IsAvif, Decode };
|
||||
}
|
||||
|
||||
} // namespace CrabbyAvif
|
||||
|
||||
} // namespace SkAvifDecoder
|
||||
|
||||
#endif // SkAvifDecoder_DEFINED
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright 2023 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
#ifndef SkBmpDecoder_DEFINED
|
||||
#define SkBmpDecoder_DEFINED
|
||||
|
||||
#include "include/codec/SkCodec.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/private/base/SkAPI.h"
|
||||
|
||||
class SkData;
|
||||
class SkStream;
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace SkBmpDecoder {
|
||||
|
||||
/** Returns true if this data claims to be a BMP image. */
|
||||
SK_API bool IsBmp(const void*, size_t);
|
||||
|
||||
/**
|
||||
* Attempts to decode the given bytes as a BMP.
|
||||
*
|
||||
* If the bytes are not a BMP, returns nullptr.
|
||||
*
|
||||
* DecodeContext is ignored
|
||||
*/
|
||||
SK_API std::unique_ptr<SkCodec> Decode(std::unique_ptr<SkStream>,
|
||||
SkCodec::Result*,
|
||||
SkCodecs::DecodeContext = nullptr);
|
||||
SK_API std::unique_ptr<SkCodec> Decode(sk_sp<const SkData>,
|
||||
SkCodec::Result*,
|
||||
SkCodecs::DecodeContext = nullptr);
|
||||
|
||||
inline constexpr SkCodecs::Decoder Decoder() {
|
||||
return { "bmp", IsBmp, Decode };
|
||||
}
|
||||
|
||||
} // namespace SkBmpDecoder
|
||||
|
||||
#endif // SkBmpDecoder_DEFINED
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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 SkCodecAnimation_DEFINED
|
||||
#define SkCodecAnimation_DEFINED
|
||||
|
||||
namespace SkCodecAnimation {
|
||||
/**
|
||||
* This specifies how the next frame is based on this frame.
|
||||
*
|
||||
* Names are based on the GIF 89a spec.
|
||||
*
|
||||
* The numbers correspond to values in a GIF.
|
||||
*/
|
||||
enum class DisposalMethod {
|
||||
/**
|
||||
* The next frame should be drawn on top of this one.
|
||||
*
|
||||
* In a GIF, a value of 0 (not specified) is also treated as Keep.
|
||||
*/
|
||||
kKeep = 1,
|
||||
|
||||
/**
|
||||
* Similar to Keep, except the area inside this frame's rectangle
|
||||
* should be cleared to the BackGround color (transparent) before
|
||||
* drawing the next frame.
|
||||
*/
|
||||
kRestoreBGColor = 2,
|
||||
|
||||
/**
|
||||
* The next frame should be drawn on top of the previous frame - i.e.
|
||||
* disregarding this one.
|
||||
*
|
||||
* In a GIF, a value of 4 is also treated as RestorePrevious.
|
||||
*/
|
||||
kRestorePrevious = 3,
|
||||
};
|
||||
|
||||
/**
|
||||
* How to blend the current frame.
|
||||
*/
|
||||
enum class Blend {
|
||||
/**
|
||||
* Blend with the prior frame as if using SkBlendMode::kSrcOver.
|
||||
*/
|
||||
kSrcOver,
|
||||
|
||||
/**
|
||||
* Blend with the prior frame as if using SkBlendMode::kSrc.
|
||||
*
|
||||
* This frame's pixels replace the destination pixels.
|
||||
*/
|
||||
kSrc,
|
||||
};
|
||||
|
||||
} // namespace SkCodecAnimation
|
||||
#endif // SkCodecAnimation_DEFINED
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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 SkEncodedImageFormat_DEFINED
|
||||
#define SkEncodedImageFormat_DEFINED
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* Enum describing format of encoded data.
|
||||
*/
|
||||
enum class SkEncodedImageFormat {
|
||||
kBMP,
|
||||
kGIF,
|
||||
kICO,
|
||||
kJPEG,
|
||||
kPNG,
|
||||
kWBMP,
|
||||
kWEBP,
|
||||
kPKM,
|
||||
kKTX,
|
||||
kASTC,
|
||||
kDNG,
|
||||
kHEIF,
|
||||
kAVIF,
|
||||
kJPEGXL,
|
||||
};
|
||||
|
||||
#endif // SkEncodedImageFormat_DEFINED
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright 2017 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkEncodedOrigin_DEFINED
|
||||
#define SkEncodedOrigin_DEFINED
|
||||
|
||||
#include "include/core/SkMatrix.h"
|
||||
|
||||
// These values match the orientation www.exif.org/Exif2-2.PDF.
|
||||
enum SkEncodedOrigin {
|
||||
kTopLeft_SkEncodedOrigin = 1, // Default
|
||||
kTopRight_SkEncodedOrigin = 2, // Reflected across y-axis
|
||||
kBottomRight_SkEncodedOrigin = 3, // Rotated 180
|
||||
kBottomLeft_SkEncodedOrigin = 4, // Reflected across x-axis
|
||||
kLeftTop_SkEncodedOrigin = 5, // Reflected across x-axis, Rotated 90 CCW
|
||||
kRightTop_SkEncodedOrigin = 6, // Rotated 90 CW
|
||||
kRightBottom_SkEncodedOrigin = 7, // Reflected across x-axis, Rotated 90 CW
|
||||
kLeftBottom_SkEncodedOrigin = 8, // Rotated 90 CCW
|
||||
kDefault_SkEncodedOrigin = kTopLeft_SkEncodedOrigin,
|
||||
kLast_SkEncodedOrigin = kLeftBottom_SkEncodedOrigin,
|
||||
};
|
||||
|
||||
/**
|
||||
* Given an encoded origin and the width and height of the source data, returns a matrix
|
||||
* that transforms the source rectangle with upper left corner at [0, 0] and origin to a correctly
|
||||
* oriented destination rectangle of [0, 0, w, h].
|
||||
*/
|
||||
static inline SkMatrix SkEncodedOriginToMatrix(SkEncodedOrigin origin, int w, int h) {
|
||||
switch (origin) {
|
||||
case kTopLeft_SkEncodedOrigin: return SkMatrix::I();
|
||||
case kTopRight_SkEncodedOrigin: return SkMatrix::MakeAll(-1, 0, w, 0, 1, 0, 0, 0, 1);
|
||||
case kBottomRight_SkEncodedOrigin: return SkMatrix::MakeAll(-1, 0, w, 0, -1, h, 0, 0, 1);
|
||||
case kBottomLeft_SkEncodedOrigin: return SkMatrix::MakeAll( 1, 0, 0, 0, -1, h, 0, 0, 1);
|
||||
case kLeftTop_SkEncodedOrigin: return SkMatrix::MakeAll( 0, 1, 0, 1, 0, 0, 0, 0, 1);
|
||||
case kRightTop_SkEncodedOrigin: return SkMatrix::MakeAll( 0, -1, w, 1, 0, 0, 0, 0, 1);
|
||||
case kRightBottom_SkEncodedOrigin: return SkMatrix::MakeAll( 0, -1, w, -1, 0, h, 0, 0, 1);
|
||||
case kLeftBottom_SkEncodedOrigin: return SkMatrix::MakeAll( 0, 1, 0, -1, 0, h, 0, 0, 1);
|
||||
}
|
||||
SK_ABORT("Unexpected origin");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a matrix equal to SkEncodedOriginToMatrix(origin, w, h).invert().
|
||||
*/
|
||||
static inline SkMatrix SkEncodedOriginToMatrixInverse(SkEncodedOrigin origin, int w, int h) {
|
||||
switch (origin) {
|
||||
case kTopLeft_SkEncodedOrigin: return SkMatrix::I();
|
||||
case kTopRight_SkEncodedOrigin: return SkMatrix::MakeAll(-1, 0, w, 0, 1, 0, 0, 0, 1);
|
||||
case kBottomRight_SkEncodedOrigin: return SkMatrix::MakeAll(-1, 0, w, 0, -1, h, 0, 0, 1);
|
||||
case kBottomLeft_SkEncodedOrigin: return SkMatrix::MakeAll( 1, 0, 0, 0, -1, h, 0, 0, 1);
|
||||
case kLeftTop_SkEncodedOrigin: return SkMatrix::MakeAll( 0, 1, 0, 1, 0, 0, 0, 0, 1);
|
||||
case kRightTop_SkEncodedOrigin: return SkMatrix::MakeAll( 0, 1, 0, -1, 0, w, 0, 0, 1);
|
||||
case kRightBottom_SkEncodedOrigin: return SkMatrix::MakeAll( 0, -1, h, -1, 0, w, 0, 0, 1);
|
||||
case kLeftBottom_SkEncodedOrigin: return SkMatrix::MakeAll( 0, -1, h, 1, 0, 0, 0, 0, 1);
|
||||
}
|
||||
SK_ABORT("Unexpected origin");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the encoded origin includes a 90 degree rotation, in which case the width
|
||||
* and height of the source data are swapped relative to a correctly oriented destination.
|
||||
*/
|
||||
static inline bool SkEncodedOriginSwapsWidthHeight(SkEncodedOrigin origin) {
|
||||
return origin >= kLeftTop_SkEncodedOrigin;
|
||||
}
|
||||
|
||||
#endif // SkEncodedOrigin_DEFINED
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright 2023 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
#ifndef SkGifDecoder_DEFINED
|
||||
#define SkGifDecoder_DEFINED
|
||||
|
||||
#include "include/codec/SkCodec.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/private/base/SkAPI.h"
|
||||
|
||||
class SkData;
|
||||
class SkStream;
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace SkGifDecoder {
|
||||
|
||||
/** Returns true if this data claims to be a GIF image. */
|
||||
SK_API bool IsGif(const void*, size_t);
|
||||
|
||||
/**
|
||||
* Attempts to decode the given bytes as a GIF.
|
||||
*
|
||||
* If the bytes are not a GIF, returns nullptr.
|
||||
*
|
||||
* DecodeContext is ignored
|
||||
*/
|
||||
SK_API std::unique_ptr<SkCodec> Decode(std::unique_ptr<SkStream>,
|
||||
SkCodec::Result*,
|
||||
SkCodecs::DecodeContext = nullptr);
|
||||
SK_API std::unique_ptr<SkCodec> Decode(sk_sp<const SkData>,
|
||||
SkCodec::Result*,
|
||||
SkCodecs::DecodeContext = nullptr);
|
||||
|
||||
inline constexpr SkCodecs::Decoder Decoder() {
|
||||
return { "gif", IsGif, Decode };
|
||||
}
|
||||
|
||||
} // namespace SkGifDecoder
|
||||
|
||||
#endif // SkGifDecoder_DEFINED
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright 2023 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
#ifndef SkIcoDecoder_DEFINED
|
||||
#define SkIcoDecoder_DEFINED
|
||||
|
||||
#include "include/codec/SkCodec.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/private/base/SkAPI.h"
|
||||
|
||||
class SkData;
|
||||
class SkStream;
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace SkIcoDecoder {
|
||||
|
||||
/** Returns true if this data claims to be a ICO image. */
|
||||
SK_API bool IsIco(const void*, size_t);
|
||||
|
||||
/**
|
||||
* Attempts to decode the given bytes as a ICO.
|
||||
*
|
||||
* If the bytes are not a ICO, returns nullptr.
|
||||
*
|
||||
* DecodeContext is ignored
|
||||
*/
|
||||
SK_API std::unique_ptr<SkCodec> Decode(std::unique_ptr<SkStream>,
|
||||
SkCodec::Result*,
|
||||
SkCodecs::DecodeContext = nullptr);
|
||||
SK_API std::unique_ptr<SkCodec> Decode(sk_sp<const SkData>,
|
||||
SkCodec::Result*,
|
||||
SkCodecs::DecodeContext = nullptr);
|
||||
|
||||
inline constexpr SkCodecs::Decoder Decoder() {
|
||||
return { "ico", IsIco, Decode };
|
||||
}
|
||||
|
||||
} // namespace SkIcoDecoder
|
||||
|
||||
#endif // SkIcoDecoder_DEFINED
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright 2023 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
#ifndef SkJpegDecoder_DEFINED
|
||||
#define SkJpegDecoder_DEFINED
|
||||
|
||||
#include "include/codec/SkCodec.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/private/base/SkAPI.h"
|
||||
|
||||
class SkData;
|
||||
class SkStream;
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace SkJpegDecoder {
|
||||
|
||||
/** Returns true if this data claims to be a JPEG image. */
|
||||
SK_API bool IsJpeg(const void*, size_t);
|
||||
|
||||
/**
|
||||
* Attempts to decode the given bytes as a JPEG.
|
||||
*
|
||||
* If the bytes are not a JPEG, returns nullptr.
|
||||
*
|
||||
* DecodeContext is ignored
|
||||
*/
|
||||
SK_API std::unique_ptr<SkCodec> Decode(std::unique_ptr<SkStream>,
|
||||
SkCodec::Result*,
|
||||
SkCodecs::DecodeContext = nullptr);
|
||||
SK_API std::unique_ptr<SkCodec> Decode(sk_sp<const SkData>,
|
||||
SkCodec::Result*,
|
||||
SkCodecs::DecodeContext = nullptr);
|
||||
|
||||
// TODO: remove after client migration
|
||||
inline std::unique_ptr<SkCodec> Decode(sk_sp<SkData> data,
|
||||
SkCodec::Result* result,
|
||||
SkCodecs::DecodeContext ctx = nullptr) {
|
||||
return Decode(sk_sp<const SkData>(static_cast<const SkData*>(data.release())), result, ctx);
|
||||
}
|
||||
|
||||
inline constexpr SkCodecs::Decoder Decoder() {
|
||||
return { "jpeg", IsJpeg, Decode };
|
||||
}
|
||||
|
||||
} // namespace SkJpegDecoder
|
||||
|
||||
#endif // SkJpegDecoder_DEFINED
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright 2023 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
#ifndef SkJpegxlDecoder_DEFINED
|
||||
#define SkJpegxlDecoder_DEFINED
|
||||
|
||||
#include "include/codec/SkCodec.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/private/base/SkAPI.h"
|
||||
|
||||
class SkData;
|
||||
class SkStream;
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace SkJpegxlDecoder {
|
||||
|
||||
/** Returns true if this data claims to be a JPEGXL image. */
|
||||
SK_API bool IsJpegxl(const void*, size_t);
|
||||
|
||||
/**
|
||||
* Attempts to decode the given bytes as a JPEGXL.
|
||||
*
|
||||
* If the bytes are not a JPEGXL, returns nullptr.
|
||||
*
|
||||
* DecodeContext is ignored
|
||||
*/
|
||||
SK_API std::unique_ptr<SkCodec> Decode(std::unique_ptr<SkStream>,
|
||||
SkCodec::Result*,
|
||||
SkCodecs::DecodeContext = nullptr);
|
||||
SK_API std::unique_ptr<SkCodec> Decode(sk_sp<const SkData>,
|
||||
SkCodec::Result*,
|
||||
SkCodecs::DecodeContext = nullptr);
|
||||
|
||||
inline constexpr SkCodecs::Decoder Decoder() {
|
||||
return { "jpegxl", IsJpegxl, Decode };
|
||||
}
|
||||
|
||||
} // namespace SkJpegxlDecoder
|
||||
|
||||
#endif // SkJpegxlDecoder_DEFINED
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright 2023 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkPixmapUtils_DEFINED
|
||||
#define SkPixmapUtils_DEFINED
|
||||
|
||||
#include "include/codec/SkEncodedOrigin.h"
|
||||
#include "include/core/SkImageInfo.h"
|
||||
#include "include/private/base/SkAPI.h"
|
||||
|
||||
class SkPixmap;
|
||||
|
||||
namespace SkPixmapUtils {
|
||||
/**
|
||||
* Copy the pixels in src into dst, applying the orientation transformations specified
|
||||
* by origin. If the inputs are invalid, this returns false and no copy is made.
|
||||
*/
|
||||
SK_API bool Orient(const SkPixmap& dst, const SkPixmap& src, SkEncodedOrigin origin);
|
||||
|
||||
/**
|
||||
* Return a copy of the provided ImageInfo with the width and height swapped.
|
||||
*/
|
||||
SK_API SkImageInfo SwapWidthHeight(const SkImageInfo& info);
|
||||
|
||||
} // namespace SkPixmapUtils
|
||||
|
||||
#endif // SkPixmapUtils_DEFINED
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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 SkPngChunkReader_DEFINED
|
||||
#define SkPngChunkReader_DEFINED
|
||||
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/core/SkTypes.h"
|
||||
|
||||
/**
|
||||
* SkPngChunkReader
|
||||
*
|
||||
* Base class for optional callbacks to retrieve meta/chunk data out of a PNG
|
||||
* encoded image as it is being decoded.
|
||||
* Used by SkCodec.
|
||||
*/
|
||||
class SkPngChunkReader : public SkRefCnt {
|
||||
public:
|
||||
/**
|
||||
* This will be called by the decoder when it sees an unknown chunk.
|
||||
*
|
||||
* Use by SkCodec:
|
||||
* Depending on the location of the unknown chunks, this callback may be
|
||||
* called by
|
||||
* - the factory (NewFromStream/NewFromData)
|
||||
* - getPixels
|
||||
* - startScanlineDecode
|
||||
* - the first call to getScanlines/skipScanlines
|
||||
* The callback may be called from a different thread (e.g. if the SkCodec
|
||||
* is passed to another thread), and it may be called multiple times, if
|
||||
* the SkCodec is used multiple times.
|
||||
*
|
||||
* @param tag Name for this type of chunk.
|
||||
* @param data Data to be interpreted by the subclass.
|
||||
* @param length Number of bytes of data in the chunk.
|
||||
* @return true to continue decoding, or false to indicate an error, which
|
||||
* will cause the decoder to not return the image.
|
||||
*/
|
||||
virtual bool readChunk(const char tag[], const void* data, size_t length) = 0;
|
||||
};
|
||||
#endif // SkPngChunkReader_DEFINED
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright 2023 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
#ifndef SkPngDecoder_DEFINED
|
||||
#define SkPngDecoder_DEFINED
|
||||
|
||||
#include "include/codec/SkCodec.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/private/base/SkAPI.h"
|
||||
|
||||
class SkData;
|
||||
class SkStream;
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace SkPngDecoder {
|
||||
|
||||
/** Returns true if this data claims to be a PNG image. */
|
||||
SK_API bool IsPng(const void*, size_t);
|
||||
|
||||
/**
|
||||
* Attempts to decode the given bytes as a PNG.
|
||||
*
|
||||
* If the bytes are not a PNG, returns nullptr.
|
||||
*
|
||||
* DecodeContext, if non-null, is expected to be a SkPngChunkReader*
|
||||
*/
|
||||
SK_API std::unique_ptr<SkCodec> Decode(std::unique_ptr<SkStream>,
|
||||
SkCodec::Result*,
|
||||
SkCodecs::DecodeContext = nullptr);
|
||||
SK_API std::unique_ptr<SkCodec> Decode(sk_sp<const SkData>,
|
||||
SkCodec::Result*,
|
||||
SkCodecs::DecodeContext = nullptr);
|
||||
|
||||
// TODO: remove after client migration
|
||||
inline std::unique_ptr<SkCodec> Decode(sk_sp<SkData> data,
|
||||
SkCodec::Result* result,
|
||||
SkCodecs::DecodeContext ctx = nullptr) {
|
||||
return Decode(sk_sp<const SkData>(static_cast<const SkData*>(data.release())), result, ctx);
|
||||
}
|
||||
|
||||
inline constexpr SkCodecs::Decoder Decoder() {
|
||||
return { "png", IsPng, Decode };
|
||||
}
|
||||
|
||||
} // namespace SkPngDecoder
|
||||
|
||||
#endif // SkPngDecoder_DEFINED
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright 2024 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
#ifndef SkPngRustDecoder_DEFINED
|
||||
#define SkPngRustDecoder_DEFINED
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "include/codec/SkCodec.h"
|
||||
#include "include/private/base/SkAPI.h"
|
||||
|
||||
class SkStream;
|
||||
|
||||
namespace SkPngRustDecoder {
|
||||
|
||||
/** Returns true if this data claims to be a PNG image. */
|
||||
SK_API bool IsPng(const void*, size_t);
|
||||
|
||||
SK_API std::unique_ptr<SkCodec> Decode(std::unique_ptr<SkStream>,
|
||||
SkCodec::Result*,
|
||||
SkCodecs::DecodeContext = nullptr);
|
||||
|
||||
inline constexpr SkCodecs::Decoder Decoder() { return {"png", IsPng, Decode}; }
|
||||
|
||||
} // namespace SkPngRustDecoder
|
||||
|
||||
#endif // SkPngRustDecoder_DEFINED
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright 2023 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
#ifndef SkRawDecoder_DEFINED
|
||||
#define SkRawDecoder_DEFINED
|
||||
|
||||
#include "include/codec/SkCodec.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/private/base/SkAPI.h"
|
||||
|
||||
class SkData;
|
||||
class SkStream;
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace SkRawDecoder {
|
||||
|
||||
inline bool IsRaw(const void*, size_t) {
|
||||
// Raw formats are tricky to detect just by reading in the first several bytes.
|
||||
// For example, PIEX might need to read 10k bytes to detect Sony's arw format
|
||||
// https://github.com/google/piex/blob/f1e15dd837c04347504149f71db67a78fbeddc73/src/image_type_recognition/image_type_recognition_lite.cc#L152
|
||||
// Thus, we just assume everything might be a RAW file and check it last.
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to decode the given bytes as a raw image.
|
||||
*
|
||||
* If the bytes are not a raw, returns nullptr.
|
||||
*
|
||||
* DecodeContext is ignored
|
||||
*/
|
||||
SK_API std::unique_ptr<SkCodec> Decode(std::unique_ptr<SkStream>,
|
||||
SkCodec::Result*,
|
||||
SkCodecs::DecodeContext = nullptr);
|
||||
SK_API std::unique_ptr<SkCodec> Decode(sk_sp<const SkData>,
|
||||
SkCodec::Result*,
|
||||
SkCodecs::DecodeContext = nullptr);
|
||||
|
||||
// This decoder will always be checked last, no matter when it is registered.
|
||||
inline constexpr SkCodecs::Decoder Decoder() {
|
||||
return { "raw", IsRaw, Decode };
|
||||
}
|
||||
|
||||
} // namespace SkRawDecoder
|
||||
|
||||
#endif // SkRawDecoder_DEFINED
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright 2023 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
#ifndef SkWbmpDecoder_DEFINED
|
||||
#define SkWbmpDecoder_DEFINED
|
||||
|
||||
#include "include/codec/SkCodec.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/private/base/SkAPI.h"
|
||||
|
||||
class SkData;
|
||||
class SkStream;
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace SkWbmpDecoder {
|
||||
|
||||
/** Returns true if this data claims to be a WBMP image. */
|
||||
SK_API bool IsWbmp(const void*, size_t);
|
||||
|
||||
/**
|
||||
* Attempts to decode the given bytes as a WBMP.
|
||||
*
|
||||
* If the bytes are not a WBMP, returns nullptr.
|
||||
*
|
||||
* DecodeContext is ignored
|
||||
*/
|
||||
SK_API std::unique_ptr<SkCodec> Decode(std::unique_ptr<SkStream>,
|
||||
SkCodec::Result*,
|
||||
SkCodecs::DecodeContext = nullptr);
|
||||
SK_API std::unique_ptr<SkCodec> Decode(sk_sp<const SkData>,
|
||||
SkCodec::Result*,
|
||||
SkCodecs::DecodeContext = nullptr);
|
||||
|
||||
inline constexpr SkCodecs::Decoder Decoder() {
|
||||
return { "wbmp", IsWbmp, Decode };
|
||||
}
|
||||
|
||||
} // namespace SkWbmpDecoder
|
||||
|
||||
#endif // SkWbmpDecoder_DEFINED
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright 2023 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
#ifndef SkWebpDecoder_DEFINED
|
||||
#define SkWebpDecoder_DEFINED
|
||||
|
||||
#include "include/codec/SkCodec.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/private/base/SkAPI.h"
|
||||
|
||||
class SkData;
|
||||
class SkStream;
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace SkWebpDecoder {
|
||||
|
||||
/** Returns true if this data claims to be a WEBP image. */
|
||||
SK_API bool IsWebp(const void*, size_t);
|
||||
|
||||
/**
|
||||
* Attempts to decode the given bytes as a WEBP.
|
||||
*
|
||||
* If the bytes are not a WEBP, returns nullptr.
|
||||
*
|
||||
* DecodeContext is ignored
|
||||
*/
|
||||
SK_API std::unique_ptr<SkCodec> Decode(std::unique_ptr<SkStream>,
|
||||
SkCodec::Result*,
|
||||
SkCodecs::DecodeContext = nullptr);
|
||||
SK_API std::unique_ptr<SkCodec> Decode(sk_sp<const SkData>,
|
||||
SkCodec::Result*,
|
||||
SkCodecs::DecodeContext = nullptr);
|
||||
|
||||
// TODO: remove after client migration
|
||||
inline std::unique_ptr<SkCodec> Decode(sk_sp<SkData> data,
|
||||
SkCodec::Result* result,
|
||||
SkCodecs::DecodeContext ctx = nullptr) {
|
||||
return Decode(sk_sp<const SkData>(static_cast<const SkData*>(data.release())), result, ctx);
|
||||
}
|
||||
|
||||
inline constexpr SkCodecs::Decoder Decoder() {
|
||||
return { "webp", IsWebp, Decode };
|
||||
}
|
||||
|
||||
} // namespace SkWebpDecoder
|
||||
|
||||
#endif // SkWebpDecoder_DEFINED
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
load("@rules_cc//cc:cc_library.bzl", "cc_library")
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
exports_files(
|
||||
["SkUserConfig.h"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
config_setting(
|
||||
name = "debug_build",
|
||||
values = {"compilation_mode": "dbg"},
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "user_config",
|
||||
hdrs = [
|
||||
"SkUserConfig.h",
|
||||
],
|
||||
defines = [
|
||||
"SK_USE_BAZEL_CONFIG_HEADER",
|
||||
] + select({
|
||||
":debug_build": ["SK_DEBUG"],
|
||||
"//conditions:default": ["SK_RELEASE"],
|
||||
}),
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
module(
|
||||
name = "skia_user_config",
|
||||
)
|
||||
|
||||
bazel_dep(name = "rules_cc", version = "0.1.1")
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
bungeman@google.com
|
||||
kjlubick@google.com
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* 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 SkUserConfig_DEFINED
|
||||
#define SkUserConfig_DEFINED
|
||||
|
||||
/* SkTypes.h, the root of the public header files, includes this file
|
||||
SkUserConfig.h after first initializing certain Skia defines, letting
|
||||
this file change or augment those flags.
|
||||
|
||||
Below are optional defines that add, subtract, or change default behavior
|
||||
in Skia. Your port can locally edit this file to enable/disable flags as
|
||||
you choose, or these can be declared on your command line (i.e. -Dfoo).
|
||||
|
||||
By default, this #include file will always default to having all the flags
|
||||
commented out, so including it will have no effect.
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/* Skia has lots of debug-only code. Often this is just null checks or other
|
||||
parameter checking, but sometimes it can be quite intrusive (e.g. check that
|
||||
each 32bit pixel is in premultiplied form). This code can be very useful
|
||||
during development, but will slow things down in a shipping product.
|
||||
|
||||
By default, these mutually exclusive flags are defined in SkTypes.h,
|
||||
based on the presence or absence of NDEBUG, but that decision can be changed
|
||||
here.
|
||||
*/
|
||||
//#define SK_DEBUG
|
||||
//#define SK_RELEASE
|
||||
|
||||
/* To write debug messages to a console, skia will call SkDebugf(...) following
|
||||
printf conventions (e.g. const char* format, ...). If you want to redirect
|
||||
this to something other than printf, define yours here
|
||||
*/
|
||||
//#define SkDebugf(...) MyFunction(__VA_ARGS__)
|
||||
|
||||
/* Skia has both debug and release asserts. When an assert fails SK_ABORT will
|
||||
be used to report an abort message. SK_ABORT is expected not to return. Skia
|
||||
provides a default implementation which will print the message with SkDebugf
|
||||
and then call sk_abort_no_print.
|
||||
*/
|
||||
//#define SK_ABORT(message, ...)
|
||||
|
||||
/* To specify a different default font strike cache memory limit, define this. If this is
|
||||
undefined, skia will use a built-in value.
|
||||
*/
|
||||
//#define SK_DEFAULT_FONT_CACHE_LIMIT (1024 * 1024)
|
||||
|
||||
/* To specify a different default font strike cache count limit, define this. If this is
|
||||
undefined, skia will use a built-in value.
|
||||
*/
|
||||
// #define SK_DEFAULT_FONT_CACHE_COUNT_LIMIT 2048
|
||||
|
||||
/* To specify the default size of the image cache, undefine this and set it to
|
||||
the desired value (in bytes). SkGraphics.h as a runtime API to set this
|
||||
value as well. If this is undefined, a built-in value will be used.
|
||||
*/
|
||||
//#define SK_DEFAULT_IMAGE_CACHE_LIMIT (1024 * 1024)
|
||||
|
||||
/* 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
|
||||
improving readability. If this is undefined, Skia will use its default
|
||||
value (e.g. 48)
|
||||
*/
|
||||
//#define SK_MAX_SIZE_FOR_LCDTEXT 48
|
||||
|
||||
/* Change the kN32_SkColorType ordering to BGRA to work in X windows.
|
||||
*/
|
||||
//#define SK_R32_SHIFT 16
|
||||
|
||||
/* This controls how much space should be pre-allocated in an SkCanvas object
|
||||
to store the SkMatrix and clip via calls to SkCanvas::save() (and balanced with
|
||||
SkCanvas::restore()).
|
||||
*/
|
||||
//#define SK_CANVAS_SAVE_RESTORE_PREALLOC_COUNT 32
|
||||
|
||||
/* Skia makes use of histogram logging macros to trace the frequency of
|
||||
events. By default, Skia provides no-op versions of these macros.
|
||||
Skia consumers can provide their own definitions of these macros to
|
||||
integrate with their histogram collection backend.
|
||||
*/
|
||||
//#define SK_HISTOGRAM_BOOLEAN(name, sample)
|
||||
//#define SK_HISTOGRAM_ENUMERATION(name, sampleEnum, enumSize)
|
||||
//#define SK_HISTOGRAM_EXACT_LINEAR(name, sample, valueMax)
|
||||
//#define SK_HISTOGRAM_CUSTOM_EXACT_LINEAR(name, sample, value_min, value_max, bucket_count)
|
||||
//#define SK_HISTOGRAM_MEMORY_KB(name, sample)
|
||||
//#define SK_HISTOGRAM_CUSTOM_COUNTS(name, sample, countMin, countMax, bucketCount)
|
||||
//#define SK_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES(name, sampleUSec, minUSec, maxUSec, bucketCount)
|
||||
|
||||
/*
|
||||
* Skia can provide extensive logging of Graphite Pipeline lifetimes.
|
||||
*/
|
||||
//#define SK_PIPELINE_LIFETIME_LOGGING
|
||||
|
||||
// To use smaller but slower mipmap builder
|
||||
//#define SK_USE_DRAWING_MIPMAP_DOWNSAMPLER
|
||||
|
||||
/* Skia tries to make use of some non-standard C++ language extensions.
|
||||
By default, Skia provides msvc and clang/gcc versions of these macros.
|
||||
Skia consumers can provide their own definitions of these macros to
|
||||
integrate with their own compilers and build system.
|
||||
*/
|
||||
//#define SK_ALWAYS_INLINE inline __attribute__((always_inline))
|
||||
//#define SK_NEVER_INLINE __attribute__((noinline))
|
||||
//#define SK_PRINTF_LIKE(A, B) __attribute__((format(printf, (A), (B))))
|
||||
//#define SK_NO_SANITIZE(A) __attribute__((no_sanitize(A)))
|
||||
//#define SK_TRIVIAL_ABI [[clang::trivial_abi]]
|
||||
|
||||
/*
|
||||
* If compiling Skia as a DLL, public APIs should be exported. Skia will set
|
||||
* SK_API to something sensible for Clang and MSVC, but if clients need to
|
||||
* customize it for their build system or compiler, they may.
|
||||
* If a client needs to use SK_API (e.g. overriding SK_ABORT), then they
|
||||
* *must* define their own, the default will not be defined prior to loading
|
||||
* this file.
|
||||
*/
|
||||
//#define SK_API __declspec(dllexport)
|
||||
|
||||
/*
|
||||
* If using DNG support, set the version of the dng_sdk being compiled against here
|
||||
* following the versioning scheme of dng_tag_valus.h
|
||||
* eg, DNG 1.4 is 0x01040000, DNG 1.7.1 is 0x01070100, etc...
|
||||
* If unspecified, DNG SDK 1.4 is assumed
|
||||
*/
|
||||
// #define SK_DNG_VERSION 0x01040000
|
||||
|
||||
/*
|
||||
* By default, Skia uses SIMD operations for many internal calculations, especially
|
||||
* for the CPU backend. These defines can be set to disable SIMD in SkVx and
|
||||
* SkRasterPipeline, respectively.
|
||||
*/
|
||||
// #define SKVX_DISABLE_SIMD
|
||||
// #define SKRP_CPU_SCALAR
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# This empty workspace file lets the SkUserConfig.h file be defined separately from Skia itself.
|
||||
# Clients can more easily set their own #defines, copts, and linkopts when building Skia using
|
||||
# Bazel.
|
||||
|
|
@ -0,0 +1,181 @@
|
|||
"""
|
||||
THIS IS THE EXTERNAL-ONLY VERSION OF THIS FILE. G3 HAS ITS OWN.
|
||||
|
||||
This file contains flags for the C++ compiler, referred to by Bazel as copts.
|
||||
|
||||
The copts in a cc_library do not flow to the children (dependencies) nor the parents
|
||||
(dependents), so we use skia_cc_library to inject them in every library along the chain.
|
||||
|
||||
Now that we have a modular build, this file could maybe go away and folded into our toolchains.
|
||||
|
||||
They are divided into several lists/selects and were initially created to be identical to the
|
||||
GN ones [2][3].
|
||||
|
||||
[2] https://github.com/google/skia/blob/2b07cdb07e88f2870260eabac708f31bc7977d08/gn/BUILDCONFIG.gn#L177-L181
|
||||
[3] https://github.com/google/skia/blob/2b07cdb07e88f2870260eabac708f31bc7977d08/gn/skia/BUILD.gn#L593-L630
|
||||
"""
|
||||
|
||||
CORE_COPTS = [
|
||||
"-fstrict-aliasing",
|
||||
] + select({
|
||||
"@platforms//os:android": [],
|
||||
"//conditions:default": [
|
||||
# On Android, this option causes the linker to fail
|
||||
# (e.g. "undefined reference to `SkString::data()'").
|
||||
"-fvisibility=hidden",
|
||||
],
|
||||
}) + select({
|
||||
"@platforms//os:windows": [],
|
||||
"//conditions:default": [
|
||||
# In Clang 14, this default was changed. We turn this off to (hopefully) make our
|
||||
# GMs more consistent and avoid some floating-point related test failures on M1 macs.
|
||||
"-ffp-contract=off",
|
||||
# Windows doesn't support position-independent code.
|
||||
"-fPIC",
|
||||
],
|
||||
}) + select({
|
||||
# Turning off RTTI reduces code size, but is necessary for connecting C++
|
||||
# and Objective-C code.
|
||||
"@platforms//os:macos": [],
|
||||
"@platforms//os:ios": [],
|
||||
"//conditions:default": [
|
||||
"-fno-rtti",
|
||||
],
|
||||
})
|
||||
|
||||
OPT_LEVEL = select({
|
||||
"//bazel/common_config_settings:debug_build": [
|
||||
"--optimize=0",
|
||||
"--debug",
|
||||
],
|
||||
"//bazel/common_config_settings:release_build": [
|
||||
"--optimize=3",
|
||||
# Strip dead code (in conjunction with linkopts)
|
||||
"-fdata-sections",
|
||||
"-ffunction-sections",
|
||||
],
|
||||
"//bazel/common_config_settings:fast_build": [
|
||||
"--optimize=0",
|
||||
"-gline-tables-only",
|
||||
],
|
||||
})
|
||||
|
||||
WARNINGS = [
|
||||
"-fcolor-diagnostics",
|
||||
"-Wall",
|
||||
"-Werror",
|
||||
"-Weverything",
|
||||
"-Wextra",
|
||||
"-Wpointer-arith",
|
||||
"-Wsign-compare",
|
||||
"-Wvla",
|
||||
#### Warnings we are unlikely to fix ####
|
||||
"-Wno-c++98-compat",
|
||||
"-Wno-c++98-compat-pedantic",
|
||||
"-Wno-covered-switch-default",
|
||||
"-Wno-declaration-after-statement",
|
||||
"-Wno-deprecated",
|
||||
"-Wno-missing-noreturn",
|
||||
"-Wno-newline-eof",
|
||||
"-Wno-old-style-cast",
|
||||
"-Wno-padded",
|
||||
"-Wno-psabi", # noisy
|
||||
"-Wno-return-std-move-in-c++11",
|
||||
"-Wno-shadow-field-in-constructor",
|
||||
"-Wno-shadow-uncaptured-local",
|
||||
"-Wno-switch-default", # Warns even when all values are covered
|
||||
"-Wno-undefined-func-template",
|
||||
"-Wno-unused-parameter", # It is common to have unused parameters in src/
|
||||
"-Wno-zero-as-null-pointer-constant", # VK_NULL_HANDLE is defined as 0
|
||||
"-Wno-unsafe-buffer-usage",
|
||||
#### Warnings we would like to fix ####
|
||||
"-Wno-abstract-vbase-init",
|
||||
"-Wno-cast-align",
|
||||
"-Wno-cast-function-type-strict",
|
||||
"-Wno-cast-qual",
|
||||
"-Wno-class-varargs",
|
||||
"-Wno-conversion", # -Wsign-conversion re-enabled for header sources
|
||||
"-Wno-disabled-macro-expansion",
|
||||
"-Wno-documentation",
|
||||
"-Wno-documentation-unknown-command",
|
||||
"-Wno-double-promotion",
|
||||
"-Wno-exit-time-destructors", # TODO: OK outside libskia
|
||||
"-Wno-float-equal",
|
||||
"-Wno-global-constructors", # TODO: OK outside libskia
|
||||
"-Wno-missing-prototypes",
|
||||
"-Wno-missing-variable-declarations",
|
||||
"-Wno-nrvo",
|
||||
"-Wno-pedantic",
|
||||
"-Wno-reserved-id-macro",
|
||||
"-Wno-reserved-identifier",
|
||||
"-Wno-shift-sign-overflow",
|
||||
"-Wno-signed-enum-bitfield",
|
||||
"-Wno-switch-enum",
|
||||
"-Wno-thread-safety-negative",
|
||||
"-Wno-undef",
|
||||
"-Wno-unreachable-code-break",
|
||||
"-Wno-unreachable-code-return",
|
||||
"-Wno-unused-macros",
|
||||
"-Wno-unused-member-function",
|
||||
"-Wno-weak-template-vtables", # This was deprecated in Clang 14 and removed in Clang 15.
|
||||
"-Wno-weak-vtables",
|
||||
# https://quuxplusone.github.io/blog/2020/08/26/wrange-loop-analysis/
|
||||
# https://bugzilla.mozilla.org/show_bug.cgi?id=1683213
|
||||
# https://reviews.llvm.org/D73007
|
||||
# May be re-enabled once clang > 12 or XCode > 12 are required.
|
||||
# When this line is removed the -Wrange-loop-construct line below can also be removed.
|
||||
"-Wno-range-loop-analysis",
|
||||
# Wno-range-loop-analysis turns off the whole group, but this warning was later split into
|
||||
# range-loop-construct and range-loop-bind-reference. We want the former but not the latter.
|
||||
# Created from
|
||||
# https://github.com/llvm/llvm-project/blob/bd08f413c089da5a56438cc8902f60df91a08a66/clang/include/clang/Basic/DiagnosticGroups.td
|
||||
"-Wrange-loop-construct",
|
||||
# Wno-deprecated turns off the whole group, but also has its own warnings like
|
||||
# out-of-line definition of constexpr static data member is redundant in C++17 and is deprecated [-Werror,-Wdeprecated]
|
||||
# but we would like others. Created from
|
||||
# https://github.com/llvm/llvm-project/blob/bd08f413c089da5a56438cc8902f60df91a08a66/clang/include/clang/Basic/DiagnosticGroups.td
|
||||
"-Wdeprecated-anon-enum-enum-conversion",
|
||||
"-Wdeprecated-array-compare",
|
||||
"-Wdeprecated-attributes",
|
||||
"-Wdeprecated-comma-subscript",
|
||||
"-Wdeprecated-copy",
|
||||
"-Wdeprecated-copy-dtor",
|
||||
"-Wdeprecated-dynamic-exception-spec",
|
||||
"-Wdeprecated-enum-compare",
|
||||
"-Wdeprecated-enum-compare-conditional",
|
||||
"-Wdeprecated-enum-enum-conversion",
|
||||
"-Wdeprecated-enum-float-conversion",
|
||||
"-Wdeprecated-increment-bool",
|
||||
"-Wdeprecated-register",
|
||||
"-Wdeprecated-this-capture",
|
||||
"-Wdeprecated-volatile",
|
||||
"-Wdeprecated-writable-strings",
|
||||
# Shows up in imgui's public headers a bunch
|
||||
"-Wno-nontrivial-memcall",
|
||||
# A catch-all for when the version of clang we are using does not have the prior options
|
||||
"-Wno-unknown-warning-option",
|
||||
# Skia must be compiled with C++20 now.
|
||||
"-Wno-c++20-compat",
|
||||
] + select({
|
||||
"@platforms//os:windows": [
|
||||
# skbug.com/40045281
|
||||
"-Wno-nonportable-system-include-path",
|
||||
"-Wno-unknown-argument",
|
||||
# Clang warns even when all enum values are covered.
|
||||
"-Wno-switch-default",
|
||||
# The Windows build fails without these options:
|
||||
"-Wno-extra-semi-stmt",
|
||||
"-Wno-invalid-constexpr",
|
||||
"-D_CRT_USE_BUILTIN_OFFSETOF",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
})
|
||||
|
||||
DEFAULT_COPTS = CORE_COPTS + OPT_LEVEL + WARNINGS
|
||||
|
||||
OBJC_COPTS = [
|
||||
"-Wno-direct-ivar-access",
|
||||
"-Wno-objc-interface-ivars",
|
||||
]
|
||||
|
||||
DEFAULT_OBJC_COPTS = DEFAULT_COPTS + OBJC_COPTS
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
"""
|
||||
THIS IS THE EXTERNAL-ONLY VERSION OF THIS FILE. G3 HAS ITS OWN.
|
||||
|
||||
This file contains flags for the C++ linker, referred to by Bazel as linkopts.
|
||||
|
||||
Now that we have a modular build, this file could maybe go away and folded into our toolchains.
|
||||
|
||||
"""
|
||||
|
||||
CORE_LINKOPTS = select({
|
||||
"@platforms//os:android": [
|
||||
"-landroid",
|
||||
"-ldl",
|
||||
"-llog", # Provides __android_log_vprint, needed by //src/ports/SkLog_android.cpp.
|
||||
],
|
||||
"//conditions:default": [],
|
||||
})
|
||||
|
||||
OPT_LEVEL = select({
|
||||
"//bazel/common_config_settings:debug_build": [],
|
||||
"//bazel/common_config_settings:fast_build_linux": [
|
||||
"-Wl,--strip-debug",
|
||||
],
|
||||
"//bazel/common_config_settings:fast_build_mac": [],
|
||||
"//bazel/common_config_settings:release_build_mac": [
|
||||
"-dead_strip",
|
||||
],
|
||||
"//bazel/common_config_settings:release_build_linux": [
|
||||
"-Wl,--gc-sections",
|
||||
"-Wl,--strip-all",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
})
|
||||
|
||||
DEFAULT_LINKOPTS = CORE_LINKOPTS + OPT_LEVEL
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
load("//bazel:skia_rules.bzl", "generate_cpp_files_for_headers", "skia_filegroup")
|
||||
|
||||
package(
|
||||
default_applicable_licenses = ["//:license"],
|
||||
)
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
PUBLIC_HEADERS = [
|
||||
"SkAlphaType.h",
|
||||
"SkAnnotation.h",
|
||||
"SkArc.h",
|
||||
"SkBBHFactory.h",
|
||||
"SkBitmap.h",
|
||||
"SkBlendMode.h",
|
||||
"SkBlender.h",
|
||||
"SkBlurTypes.h",
|
||||
"SkCPUContext.h",
|
||||
"SkCPURecorder.h",
|
||||
"SkCanvas.h",
|
||||
"SkCanvasVirtualEnforcer.h",
|
||||
"SkCapabilities.h",
|
||||
"SkClipOp.h",
|
||||
"SkColor.h",
|
||||
"SkColorFilter.h",
|
||||
"SkColorSpace.h",
|
||||
"SkColorTable.h",
|
||||
"SkColorType.h",
|
||||
"SkContourMeasure.h",
|
||||
"SkCoverageMode.h",
|
||||
"SkCubicMap.h",
|
||||
"SkData.h",
|
||||
"SkDataTable.h",
|
||||
"SkDocument.h",
|
||||
"SkDrawable.h",
|
||||
"SkExecutor.h",
|
||||
"SkFlattenable.h",
|
||||
"SkFont.h",
|
||||
"SkFontArguments.h",
|
||||
"SkFontMetrics.h",
|
||||
"SkFontMgr.h",
|
||||
"SkFontParameters.h",
|
||||
"SkFontScanner.h",
|
||||
"SkFontStyle.h",
|
||||
"SkFontTypes.h",
|
||||
"SkFourByteTag.h",
|
||||
"SkGraphics.h",
|
||||
"SkImage.h",
|
||||
"SkImageFilter.h",
|
||||
"SkImageGenerator.h",
|
||||
"SkImageInfo.h",
|
||||
"SkM44.h",
|
||||
"SkMallocPixelRef.h",
|
||||
"SkMaskFilter.h",
|
||||
"SkMatrix.h",
|
||||
"SkMesh.h",
|
||||
"SkMilestone.h",
|
||||
"SkOpenTypeSVGDecoder.h",
|
||||
"SkOverdrawCanvas.h",
|
||||
"SkPaint.h",
|
||||
"SkPath.h",
|
||||
"SkPathBuilder.h",
|
||||
"SkPathEffect.h",
|
||||
"SkPathIter.h",
|
||||
"SkPathMeasure.h",
|
||||
"SkPathTypes.h",
|
||||
"SkPathUtils.h",
|
||||
"SkPicture.h",
|
||||
"SkPictureRecorder.h",
|
||||
"SkPixelRef.h",
|
||||
"SkPixmap.h",
|
||||
"SkPoint.h",
|
||||
"SkPoint3.h",
|
||||
"SkRRect.h",
|
||||
"SkRSXform.h",
|
||||
"SkRasterHandleAllocator.h",
|
||||
"SkRecorder.h",
|
||||
"SkRect.h",
|
||||
"SkRefCnt.h",
|
||||
"SkRegion.h",
|
||||
"SkSamplingOptions.h",
|
||||
"SkScalar.h",
|
||||
"SkSerialProcs.h",
|
||||
"SkShader.h",
|
||||
"SkSize.h",
|
||||
"SkSpan.h",
|
||||
"SkStream.h",
|
||||
"SkString.h",
|
||||
"SkStrikeRef.h",
|
||||
"SkStrokeRec.h",
|
||||
"SkSurface.h",
|
||||
"SkSurfaceProps.h",
|
||||
"SkSwizzle.h",
|
||||
"SkTextBlob.h",
|
||||
"SkTextureCompressionType.h",
|
||||
"SkTileMode.h",
|
||||
"SkTiledImageUtils.h",
|
||||
"SkTraceMemoryDump.h",
|
||||
"SkTypeface.h",
|
||||
"SkTypes.h",
|
||||
"SkUnPreMultiply.h",
|
||||
"SkVertices.h",
|
||||
"SkYUVAInfo.h",
|
||||
"SkYUVAPixmaps.h",
|
||||
]
|
||||
|
||||
skia_filegroup(
|
||||
name = "core_hdrs",
|
||||
srcs = PUBLIC_HEADERS,
|
||||
visibility = ["//src/core:__pkg__"],
|
||||
)
|
||||
|
||||
generate_cpp_files_for_headers(
|
||||
name = "headers_to_compile",
|
||||
headers = PUBLIC_HEADERS,
|
||||
)
|
||||
|
||||
skia_filegroup(
|
||||
name = "opts_srcs",
|
||||
srcs = [
|
||||
"SkAlphaType.h",
|
||||
"SkColor.h",
|
||||
"SkScalar.h",
|
||||
"SkTypes.h",
|
||||
],
|
||||
visibility = ["//src/opts:__pkg__"],
|
||||
)
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright 2022 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkAlphaType_DEFINED
|
||||
#define SkAlphaType_DEFINED
|
||||
|
||||
/** \enum SkAlphaType
|
||||
Describes how to interpret the alpha component of a pixel. A pixel may
|
||||
be opaque, or alpha, describing multiple levels of transparency.
|
||||
|
||||
In simple blending, alpha weights the draw color and the destination
|
||||
color to create a new color. If alpha describes a weight from zero to one:
|
||||
|
||||
new color = draw color * alpha + destination color * (1 - alpha)
|
||||
|
||||
In practice alpha is encoded in two or more bits, where 1.0 equals all bits set.
|
||||
|
||||
RGB may have alpha included in each component value; the stored
|
||||
value is the original RGB multiplied by alpha. Premultiplied color
|
||||
components improve performance.
|
||||
*/
|
||||
enum SkAlphaType : int {
|
||||
kUnknown_SkAlphaType, //!< uninitialized
|
||||
kOpaque_SkAlphaType, //!< pixel is opaque
|
||||
kPremul_SkAlphaType, //!< pixel components are premultiplied by alpha
|
||||
kUnpremul_SkAlphaType, //!< pixel components are independent of alpha
|
||||
kLastEnum_SkAlphaType = kUnpremul_SkAlphaType, //!< last valid value
|
||||
};
|
||||
|
||||
/** Returns true if SkAlphaType equals kOpaque_SkAlphaType.
|
||||
|
||||
kOpaque_SkAlphaType is a hint that the SkColorType is opaque, or that all
|
||||
alpha values are set to their 1.0 equivalent. If SkAlphaType is
|
||||
kOpaque_SkAlphaType, and SkColorType is not opaque, then the result of
|
||||
drawing any pixel with a alpha value less than 1.0 is undefined.
|
||||
*/
|
||||
static inline bool SkAlphaTypeIsOpaque(SkAlphaType at) {
|
||||
return kOpaque_SkAlphaType == at;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkAnnotation_DEFINED
|
||||
#define SkAnnotation_DEFINED
|
||||
|
||||
#include "include/core/SkTypes.h"
|
||||
|
||||
class SkData;
|
||||
struct SkPoint;
|
||||
struct SkRect;
|
||||
class SkCanvas;
|
||||
|
||||
/**
|
||||
* Annotate the canvas by associating the specified URL with the
|
||||
* specified rectangle (in local coordinates, just like drawRect).
|
||||
*
|
||||
* The URL is expected to be escaped and be valid 7-bit ASCII.
|
||||
*
|
||||
* If the backend of this canvas does not support annotations, this call is
|
||||
* safely ignored.
|
||||
*
|
||||
* The caller is responsible for managing its ownership of the SkData.
|
||||
*/
|
||||
SK_API void SkAnnotateRectWithURL(SkCanvas*, const SkRect&, SkData*);
|
||||
|
||||
/**
|
||||
* Annotate the canvas by associating a name with the specified point.
|
||||
*
|
||||
* If the backend of this canvas does not support annotations, this call is
|
||||
* safely ignored.
|
||||
*
|
||||
* The caller is responsible for managing its ownership of the SkData.
|
||||
*/
|
||||
SK_API void SkAnnotateNamedDestination(SkCanvas*, const SkPoint&, SkData*);
|
||||
|
||||
/**
|
||||
* Annotate the canvas by making the specified rectangle link to a named
|
||||
* destination.
|
||||
*
|
||||
* If the backend of this canvas does not support annotations, this call is
|
||||
* safely ignored.
|
||||
*
|
||||
* The caller is responsible for managing its ownership of the SkData.
|
||||
*/
|
||||
SK_API void SkAnnotateLinkToDestination(SkCanvas*, const SkRect&, SkData*);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright 2024 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkArc_DEFINED
|
||||
#define SkArc_DEFINED
|
||||
|
||||
#include "include/core/SkRect.h"
|
||||
#include "include/core/SkScalar.h"
|
||||
|
||||
// Represents an arc along an oval boundary, or a closed wedge of the oval.
|
||||
struct SkArc {
|
||||
enum class Type : bool {
|
||||
kArc, // An arc along the perimeter of the oval
|
||||
kWedge // A closed wedge that includes the oval's center
|
||||
};
|
||||
|
||||
SkArc() = default;
|
||||
SkArc(const SkArc& arc) = default;
|
||||
SkArc& operator=(const SkArc& arc) = default;
|
||||
|
||||
const SkRect& oval() const { return fOval; }
|
||||
SkScalar startAngle() const { return fStartAngle; }
|
||||
SkScalar sweepAngle() const { return fSweepAngle; }
|
||||
bool isWedge() const { return fType == Type::kWedge; }
|
||||
|
||||
friend bool operator==(const SkArc& a, const SkArc& b) {
|
||||
return a.fOval == b.fOval && a.fStartAngle == b.fStartAngle &&
|
||||
a.fSweepAngle == b.fSweepAngle && a.fType == b.fType;
|
||||
}
|
||||
|
||||
friend bool operator!=(const SkArc& a, const SkArc& b) { return !(a == b); }
|
||||
|
||||
// Preferred factory that explicitly states which type of arc
|
||||
static SkArc Make(const SkRect& oval,
|
||||
SkScalar startAngleDegrees,
|
||||
SkScalar sweepAngleDegrees,
|
||||
Type type) {
|
||||
return SkArc(oval, startAngleDegrees, sweepAngleDegrees, type);
|
||||
}
|
||||
|
||||
// Deprecated factory to assist with legacy code based on `useCenter`
|
||||
static SkArc Make(const SkRect& oval,
|
||||
SkScalar startAngleDegrees,
|
||||
SkScalar sweepAngleDegrees,
|
||||
bool useCenter) {
|
||||
return SkArc(
|
||||
oval, startAngleDegrees, sweepAngleDegrees, useCenter ? Type::kWedge : Type::kArc);
|
||||
}
|
||||
|
||||
// Bounds of oval containing the arc.
|
||||
SkRect fOval = SkRect::MakeEmpty();
|
||||
|
||||
// Angle in degrees where the arc begins. Zero means horizontally to the right.
|
||||
SkScalar fStartAngle = 0;
|
||||
// Sweep angle in degrees; positive is clockwise.
|
||||
SkScalar fSweepAngle = 0;
|
||||
|
||||
Type fType = Type::kArc;
|
||||
|
||||
private:
|
||||
SkArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, Type type)
|
||||
: fOval(oval), fStartAngle(startAngle), fSweepAngle(sweepAngle), fType(type) {}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright 2014 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkBBHFactory_DEFINED
|
||||
#define SkBBHFactory_DEFINED
|
||||
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/core/SkTypes.h"
|
||||
|
||||
// TODO(kjlubick) fix client users and then make this a forward declare
|
||||
#include "include/core/SkRect.h" // IWYU pragma: keep
|
||||
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
|
||||
class SkBBoxHierarchy : public SkRefCnt {
|
||||
public:
|
||||
struct Metadata {
|
||||
bool isDraw; // The corresponding SkRect bounds a draw command, not a pure state change.
|
||||
};
|
||||
|
||||
/**
|
||||
* Insert N bounding boxes into the hierarchy.
|
||||
*/
|
||||
virtual void insert(const SkRect[], int N) = 0;
|
||||
virtual void insert(const SkRect[], const Metadata[], int N);
|
||||
|
||||
/**
|
||||
* Populate results with the indices of bounding boxes intersecting that query.
|
||||
*/
|
||||
virtual void search(const SkRect& query, std::vector<int>* results) const = 0;
|
||||
|
||||
/**
|
||||
* Return approximate size in memory of *this.
|
||||
*/
|
||||
virtual size_t bytesUsed() const = 0;
|
||||
|
||||
protected:
|
||||
SkBBoxHierarchy() = default;
|
||||
SkBBoxHierarchy(const SkBBoxHierarchy&) = delete;
|
||||
SkBBoxHierarchy& operator=(const SkBBoxHierarchy&) = delete;
|
||||
};
|
||||
|
||||
class SK_API SkBBHFactory {
|
||||
public:
|
||||
/**
|
||||
* Allocate a new SkBBoxHierarchy. Return NULL on failure.
|
||||
*/
|
||||
virtual sk_sp<SkBBoxHierarchy> operator()() const = 0;
|
||||
virtual ~SkBBHFactory() {}
|
||||
|
||||
protected:
|
||||
SkBBHFactory() = default;
|
||||
SkBBHFactory(const SkBBHFactory&) = delete;
|
||||
SkBBHFactory& operator=(const SkBBHFactory&) = delete;
|
||||
};
|
||||
|
||||
class SK_API SkRTreeFactory : public SkBBHFactory {
|
||||
public:
|
||||
sk_sp<SkBBoxHierarchy> operator()() const override;
|
||||
};
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* 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
|
||||
|
||||
#include "include/core/SkTypes.h"
|
||||
|
||||
/**
|
||||
* Blends are operators that take in two colors (source, destination) and return a new color.
|
||||
* Many of these operate the same on all 4 components: red, green, blue, alpha. For these,
|
||||
* we just document what happens to one component, rather than naming each one separately.
|
||||
*
|
||||
* Different SkColorTypes have different representations for color components:
|
||||
* 8-bit: 0..255
|
||||
* 6-bit: 0..63
|
||||
* 5-bit: 0..31
|
||||
* 4-bit: 0..15
|
||||
* floats: 0...1
|
||||
*
|
||||
* The documentation is expressed as if the component values are always 0..1 (floats).
|
||||
*
|
||||
* For brevity, the documentation uses the following abbreviations
|
||||
* s : source
|
||||
* d : destination
|
||||
* sa : source alpha
|
||||
* da : destination alpha
|
||||
*
|
||||
* Results are abbreviated
|
||||
* r : if all 4 components are computed in the same manner
|
||||
* ra : result alpha component
|
||||
* rc : result "color": red, green, blue components
|
||||
*/
|
||||
enum class SkBlendMode {
|
||||
kClear, //!< r = 0
|
||||
kSrc, //!< r = s
|
||||
kDst, //!< r = d
|
||||
kSrcOver, //!< r = s + (1-sa)*d
|
||||
kDstOver, //!< r = d + (1-da)*s
|
||||
kSrcIn, //!< r = s * da
|
||||
kDstIn, //!< r = d * sa
|
||||
kSrcOut, //!< r = s * (1-da)
|
||||
kDstOut, //!< r = d * (1-sa)
|
||||
kSrcATop, //!< r = s*da + d*(1-sa)
|
||||
kDstATop, //!< r = d*sa + s*(1-da)
|
||||
kXor, //!< r = s*(1-da) + d*(1-sa)
|
||||
kPlus, //!< r = min(s + d, 1)
|
||||
kModulate, //!< r = s*d
|
||||
kScreen, //!< r = s + d - s*d
|
||||
|
||||
kOverlay, //!< multiply or screen, depending on destination
|
||||
kDarken, //!< rc = s + d - max(s*da, d*sa), ra = kSrcOver
|
||||
kLighten, //!< rc = s + d - min(s*da, d*sa), ra = kSrcOver
|
||||
kColorDodge, //!< brighten destination to reflect source
|
||||
kColorBurn, //!< darken destination to reflect source
|
||||
kHardLight, //!< multiply or screen, depending on source
|
||||
kSoftLight, //!< lighten or darken, depending on source
|
||||
kDifference, //!< rc = s + d - 2*(min(s*da, d*sa)), ra = kSrcOver
|
||||
kExclusion, //!< rc = s + d - two(s*d), ra = kSrcOver
|
||||
kMultiply, //!< r = s*(1-da) + d*(1-sa) + s*d
|
||||
|
||||
kHue, //!< hue of source with saturation and luminosity of destination
|
||||
kSaturation, //!< saturation of source with hue and luminosity of destination
|
||||
kColor, //!< hue and saturation of source with luminosity of destination
|
||||
kLuminosity, //!< luminosity of source with hue and saturation of destination
|
||||
|
||||
kLastCoeffMode = kScreen, //!< last porter duff blend mode
|
||||
kLastSeparableMode = kMultiply, //!< last blend mode operating separately on components
|
||||
kLastMode = kLuminosity, //!< last valid value
|
||||
};
|
||||
|
||||
static constexpr int kSkBlendModeCount = static_cast<int>(SkBlendMode::kLastMode) + 1;
|
||||
|
||||
/**
|
||||
* For Porter-Duff SkBlendModes (those <= kLastCoeffMode), these coefficients describe the blend
|
||||
* equation used. Coefficient-based blend modes specify an equation:
|
||||
* ('dstCoeff' * dst + 'srcCoeff' * src), where the coefficient values are constants, functions of
|
||||
* the src or dst alpha, or functions of the src or dst color.
|
||||
*/
|
||||
enum class SkBlendModeCoeff {
|
||||
kZero, /** 0 */
|
||||
kOne, /** 1 */
|
||||
kSC, /** src color */
|
||||
kISC, /** inverse src color (i.e. 1 - sc) */
|
||||
kDC, /** dst color */
|
||||
kIDC, /** inverse dst color (i.e. 1 - dc) */
|
||||
kSA, /** src alpha */
|
||||
kISA, /** inverse src alpha (i.e. 1 - sa) */
|
||||
kDA, /** dst alpha */
|
||||
kIDA, /** inverse dst alpha (i.e. 1 - da) */
|
||||
|
||||
kCoeffCount
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if 'mode' is a coefficient-based blend mode (<= kLastCoeffMode). If true is
|
||||
* returned, the mode's src and dst coefficient functions are set in 'src' and 'dst'.
|
||||
*/
|
||||
SK_API bool SkBlendMode_AsCoeff(SkBlendMode mode, SkBlendModeCoeff* src, SkBlendModeCoeff* dst);
|
||||
|
||||
|
||||
/** Returns name of blendMode as null-terminated C string.
|
||||
|
||||
@return C string
|
||||
*/
|
||||
SK_API const char* SkBlendMode_Name(SkBlendMode blendMode);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright 2021 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkBlender_DEFINED
|
||||
#define SkBlender_DEFINED
|
||||
|
||||
#include "include/core/SkBlendMode.h"
|
||||
#include "include/core/SkFlattenable.h"
|
||||
|
||||
/**
|
||||
* SkBlender represents a custom blend function in the Skia pipeline. A blender combines a source
|
||||
* color (the result of our paint) and destination color (from the canvas) into a final color.
|
||||
*/
|
||||
class SK_API SkBlender : public SkFlattenable {
|
||||
public:
|
||||
/**
|
||||
* Create a blender that implements the specified BlendMode.
|
||||
*/
|
||||
static sk_sp<SkBlender> Mode(SkBlendMode mode);
|
||||
|
||||
private:
|
||||
SkBlender() = default;
|
||||
friend class SkBlenderBase;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright 2014 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkBlurTypes_DEFINED
|
||||
#define SkBlurTypes_DEFINED
|
||||
|
||||
enum SkBlurStyle : int {
|
||||
kNormal_SkBlurStyle, //!< fuzzy inside and outside
|
||||
kSolid_SkBlurStyle, //!< solid inside, fuzzy outside
|
||||
kOuter_SkBlurStyle, //!< nothing inside, fuzzy outside
|
||||
kInner_SkBlurStyle, //!< fuzzy inside, nothing outside
|
||||
|
||||
kLastEnum_SkBlurStyle = kInner_SkBlurStyle,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright 2025 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
#ifndef skcpu_Context_DEFINED
|
||||
#define skcpu_Context_DEFINED
|
||||
|
||||
#include "include/private/base/SkAPI.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace skcpu {
|
||||
class Recorder;
|
||||
|
||||
class SK_API Context {
|
||||
public:
|
||||
struct Options {};
|
||||
|
||||
std::unique_ptr<Recorder> makeRecorder() const;
|
||||
|
||||
static std::unique_ptr<const Context> Make(const Options&);
|
||||
static std::unique_ptr<const Context> Make();
|
||||
|
||||
protected:
|
||||
Context() = default;
|
||||
};
|
||||
} // namespace skcpu
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright 2025 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef skcpu_Recorder_DEFINED
|
||||
#define skcpu_Recorder_DEFINED
|
||||
|
||||
#include <cstdint>
|
||||
#include "include/core/SkRecorder.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/private/base/SkAPI.h"
|
||||
|
||||
class SkCanvas;
|
||||
class SkContentID;
|
||||
class SkSurface;
|
||||
class SkSurfaceProps;
|
||||
struct SkImageInfo;
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace skcpu {
|
||||
|
||||
class SK_API Recorder : public SkRecorder {
|
||||
public:
|
||||
/** Returns a non-null global context. Can be used as a means of transitioning onto
|
||||
* new APIs when a skcpu::Context/Recorder has not been piped down into the code paths
|
||||
*/
|
||||
static Recorder* TODO();
|
||||
|
||||
SkRecorder::Type type() const final { return SkRecorder::Type::kCPU; }
|
||||
skcpu::Recorder* cpuRecorder() final { return this; }
|
||||
|
||||
/** Allocates a bitmap-backed SkSurface. SkCanvas returned by SkSurface draws directly into
|
||||
* those allocated pixels, which are zeroed before use. Pixel memory size is imageInfo.height()
|
||||
* times imageInfo.minRowBytes() or rowBytes, if provided and non-zero.
|
||||
*
|
||||
* Pixel memory is deleted when SkSurface is deleted.
|
||||
*
|
||||
* Validity constraints include:
|
||||
* - info dimensions are greater than zero;
|
||||
* - info contains SkColorType and SkAlphaType supported by raster surface.
|
||||
*
|
||||
* @param imageInfo width, height, SkColorType, SkAlphaType, SkColorSpace,
|
||||
* of raster surface; width and height must be greater than zero
|
||||
* @param rowBytes interval from one SkSurface row to the next.
|
||||
* @param props LCD striping orientation and setting for device independent fonts;
|
||||
* may be nullptr
|
||||
* @return SkSurface if parameters are valid and memory was allocated, else nullptr.
|
||||
*/
|
||||
sk_sp<SkSurface> makeBitmapSurface(const SkImageInfo& imageInfo,
|
||||
size_t rowBytes,
|
||||
const SkSurfaceProps* surfaceProps);
|
||||
sk_sp<SkSurface> makeBitmapSurface(const SkImageInfo& imageInfo,
|
||||
const SkSurfaceProps* surfaceProps = nullptr);
|
||||
|
||||
private:
|
||||
// TODO (b/412351769): Implement this so we can capture from a CPU Recorder.
|
||||
SkCanvas* makeCaptureCanvas(SkCanvas*) final { return nullptr; }
|
||||
SkContentID createCaptureBreakpoint(SkSurface*) final;
|
||||
};
|
||||
|
||||
inline Recorder* AsRecorder(SkRecorder* recorder) {
|
||||
if (!recorder) {
|
||||
return nullptr;
|
||||
}
|
||||
if (recorder->type() != SkRecorder::Type::kCPU) {
|
||||
return nullptr;
|
||||
}
|
||||
return static_cast<Recorder*>(recorder);
|
||||
}
|
||||
|
||||
} // namespace skcpu
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright 2018 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkCanvasVirtualEnforcer_DEFINED
|
||||
#define SkCanvasVirtualEnforcer_DEFINED
|
||||
|
||||
#include "include/core/SkCanvas.h"
|
||||
|
||||
// If you would ordinarily want to inherit from Base (eg SkCanvas, SkNWayCanvas), instead
|
||||
// inherit from SkCanvasVirtualEnforcer<Base>, which will make the build fail if you forget
|
||||
// to override one of SkCanvas' key virtual hooks.
|
||||
template <typename Base>
|
||||
class SkCanvasVirtualEnforcer : public Base {
|
||||
public:
|
||||
using Base::Base;
|
||||
|
||||
protected:
|
||||
void onDrawPaint(const SkPaint& paint) override = 0;
|
||||
void onDrawBehind(const SkPaint&) override {} // make zero after android updates
|
||||
void onDrawRect(const SkRect& rect, const SkPaint& paint) override = 0;
|
||||
void onDrawRRect(const SkRRect& rrect, const SkPaint& paint) override = 0;
|
||||
void onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
|
||||
const SkPaint& paint) override = 0;
|
||||
void onDrawOval(const SkRect& rect, const SkPaint& paint) override = 0;
|
||||
void onDrawArc(const SkRect& rect, SkScalar startAngle, SkScalar sweepAngle, bool useCenter,
|
||||
const SkPaint& paint) override = 0;
|
||||
void onDrawPath(const SkPath& path, const SkPaint& paint) override = 0;
|
||||
void onDrawRegion(const SkRegion& region, const SkPaint& paint) override = 0;
|
||||
|
||||
void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
|
||||
const SkPaint& paint) override = 0;
|
||||
|
||||
void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
|
||||
const SkPoint texCoords[4], SkBlendMode mode,
|
||||
const SkPaint& paint) override = 0;
|
||||
void onDrawPoints(SkCanvas::PointMode mode, size_t count, const SkPoint pts[],
|
||||
const SkPaint& paint) override = 0;
|
||||
|
||||
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
|
||||
// This is under active development for Chrome and not used in Android. Hold off on adding
|
||||
// implementations in Android's SkCanvas subclasses until this stabilizes.
|
||||
void onDrawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4],
|
||||
SkCanvas::QuadAAFlags aaFlags, const SkColor4f& color, SkBlendMode mode) override {}
|
||||
#else
|
||||
void onDrawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4],
|
||||
SkCanvas::QuadAAFlags aaFlags, const SkColor4f& color, SkBlendMode mode) override = 0;
|
||||
#endif
|
||||
|
||||
void onDrawAnnotation(const SkRect& rect, const char key[], SkData* value) override = 0;
|
||||
void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&) override = 0;
|
||||
|
||||
void onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) override = 0;
|
||||
void onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
|
||||
const SkPaint* paint) override = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright 2022 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkCapabilities_DEFINED
|
||||
#define SkCapabilities_DEFINED
|
||||
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/core/SkTypes.h"
|
||||
#include "include/sksl/SkSLVersion.h"
|
||||
|
||||
namespace SkSL { struct ShaderCaps; }
|
||||
|
||||
namespace skgpu::graphite { class Caps; }
|
||||
|
||||
class SK_API SkCapabilities : public SkRefCnt {
|
||||
public:
|
||||
static sk_sp<const SkCapabilities> RasterBackend();
|
||||
|
||||
SkSL::Version skslVersion() const { return fSkSLVersion; }
|
||||
|
||||
protected:
|
||||
friend class skgpu::graphite::Caps; // for ctor
|
||||
|
||||
SkCapabilities() = default;
|
||||
|
||||
void initSkCaps(const SkSL::ShaderCaps*);
|
||||
|
||||
SkSL::Version fSkSLVersion = SkSL::Version::k100;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* 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 "include/core/SkTypes.h"
|
||||
|
||||
enum class SkClipOp {
|
||||
kDifference = 0,
|
||||
kIntersect = 1,
|
||||
kMax_EnumValue = kIntersect
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,469 @@
|
|||
/*
|
||||
* 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 SkColor_DEFINED
|
||||
#define SkColor_DEFINED
|
||||
|
||||
#include "include/core/SkAlphaType.h"
|
||||
#include "include/core/SkScalar.h"
|
||||
#include "include/core/SkTypes.h"
|
||||
#include "include/private/base/SkCPUTypes.h"
|
||||
#include "include/private/base/SkTPin.h"
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
||||
/** \file SkColor.h
|
||||
|
||||
Types, consts, functions, and macros for colors.
|
||||
*/
|
||||
|
||||
/** 8-bit type for an alpha value. 255 is 100% opaque, zero is 100% transparent.
|
||||
*/
|
||||
typedef uint8_t SkAlpha;
|
||||
|
||||
/** 32-bit ARGB color value, unpremultiplied. Color components are always in
|
||||
a known order. This is different from SkPMColor, which has its bytes in a configuration
|
||||
dependent order, to match the format of kBGRA_8888_SkColorType bitmaps. SkColor
|
||||
is the type used to specify colors in SkPaint and in gradients.
|
||||
|
||||
Color that is premultiplied has the same component values as color
|
||||
that is unpremultiplied if alpha is 255, fully opaque, although may have the
|
||||
component values in a different order.
|
||||
*/
|
||||
typedef uint32_t SkColor;
|
||||
|
||||
/** Returns color value from 8-bit component values. Asserts if SK_DEBUG is defined
|
||||
if a, r, g, or b exceed 255. Since color is unpremultiplied, a may be smaller
|
||||
than the largest of r, g, and b.
|
||||
|
||||
@param a amount of alpha, from fully transparent (0) to fully opaque (255)
|
||||
@param r amount of red, from no red (0) to full red (255)
|
||||
@param g amount of green, from no green (0) to full green (255)
|
||||
@param b amount of blue, from no blue (0) to full blue (255)
|
||||
@return color and alpha, unpremultiplied
|
||||
*/
|
||||
static constexpr inline SkColor SkColorSetARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
|
||||
return SkASSERT(a <= 255 && r <= 255 && g <= 255 && b <= 255),
|
||||
(a << 24) | (r << 16) | (g << 8) | (b << 0);
|
||||
}
|
||||
|
||||
/** Returns color value from 8-bit component values, with alpha set
|
||||
fully opaque to 255.
|
||||
*/
|
||||
#define SkColorSetRGB(r, g, b) SkColorSetARGB(0xFF, r, g, b)
|
||||
|
||||
/** Returns alpha byte from color value.
|
||||
*/
|
||||
#define SkColorGetA(color) (((color) >> 24) & 0xFF)
|
||||
|
||||
/** Returns red component of color, from zero to 255.
|
||||
*/
|
||||
#define SkColorGetR(color) (((color) >> 16) & 0xFF)
|
||||
|
||||
/** Returns green component of color, from zero to 255.
|
||||
*/
|
||||
#define SkColorGetG(color) (((color) >> 8) & 0xFF)
|
||||
|
||||
/** Returns blue component of color, from zero to 255.
|
||||
*/
|
||||
#define SkColorGetB(color) (((color) >> 0) & 0xFF)
|
||||
|
||||
/** Returns unpremultiplied color with red, blue, and green set from c; and alpha set
|
||||
from a. Alpha component of c is ignored and is replaced by a in result.
|
||||
|
||||
@param c packed RGB, eight bits per component
|
||||
@param a alpha: transparent at zero, fully opaque at 255
|
||||
@return color with transparency
|
||||
*/
|
||||
[[nodiscard]] static constexpr inline SkColor SkColorSetA(SkColor c, U8CPU a) {
|
||||
return (c & 0x00FFFFFF) | (a << 24);
|
||||
}
|
||||
|
||||
/** Represents fully transparent SkAlpha value. SkAlpha ranges from zero,
|
||||
fully transparent; to 255, fully opaque.
|
||||
*/
|
||||
constexpr SkAlpha SK_AlphaTRANSPARENT = 0x00;
|
||||
|
||||
/** Represents fully opaque SkAlpha value. SkAlpha ranges from zero,
|
||||
fully transparent; to 255, fully opaque.
|
||||
*/
|
||||
constexpr SkAlpha SK_AlphaOPAQUE = 0xFF;
|
||||
|
||||
/** Represents fully transparent SkColor. May be used to initialize a destination
|
||||
containing a mask or a non-rectangular image.
|
||||
*/
|
||||
constexpr SkColor SK_ColorTRANSPARENT = SkColorSetARGB(0x00, 0x00, 0x00, 0x00);
|
||||
|
||||
/** Represents fully opaque black.
|
||||
*/
|
||||
constexpr SkColor SK_ColorBLACK = SkColorSetARGB(0xFF, 0x00, 0x00, 0x00);
|
||||
|
||||
/** Represents fully opaque dark gray.
|
||||
Note that SVG dark gray is equivalent to 0xFFA9A9A9.
|
||||
*/
|
||||
constexpr SkColor SK_ColorDKGRAY = SkColorSetARGB(0xFF, 0x44, 0x44, 0x44);
|
||||
|
||||
/** Represents fully opaque gray.
|
||||
Note that HTML gray is equivalent to 0xFF808080.
|
||||
*/
|
||||
constexpr SkColor SK_ColorGRAY = SkColorSetARGB(0xFF, 0x88, 0x88, 0x88);
|
||||
|
||||
/** Represents fully opaque light gray. HTML silver is equivalent to 0xFFC0C0C0.
|
||||
Note that SVG light gray is equivalent to 0xFFD3D3D3.
|
||||
*/
|
||||
constexpr SkColor SK_ColorLTGRAY = SkColorSetARGB(0xFF, 0xCC, 0xCC, 0xCC);
|
||||
|
||||
/** Represents fully opaque white.
|
||||
*/
|
||||
constexpr SkColor SK_ColorWHITE = SkColorSetARGB(0xFF, 0xFF, 0xFF, 0xFF);
|
||||
|
||||
/** Represents fully opaque red.
|
||||
*/
|
||||
constexpr SkColor SK_ColorRED = SkColorSetARGB(0xFF, 0xFF, 0x00, 0x00);
|
||||
|
||||
/** Represents fully opaque green. HTML lime is equivalent.
|
||||
Note that HTML green is equivalent to 0xFF008000.
|
||||
*/
|
||||
constexpr SkColor SK_ColorGREEN = SkColorSetARGB(0xFF, 0x00, 0xFF, 0x00);
|
||||
|
||||
/** Represents fully opaque blue.
|
||||
*/
|
||||
constexpr SkColor SK_ColorBLUE = SkColorSetARGB(0xFF, 0x00, 0x00, 0xFF);
|
||||
|
||||
/** Represents fully opaque yellow.
|
||||
*/
|
||||
constexpr SkColor SK_ColorYELLOW = SkColorSetARGB(0xFF, 0xFF, 0xFF, 0x00);
|
||||
|
||||
/** Represents fully opaque cyan. HTML aqua is equivalent.
|
||||
*/
|
||||
constexpr SkColor SK_ColorCYAN = SkColorSetARGB(0xFF, 0x00, 0xFF, 0xFF);
|
||||
|
||||
/** Represents fully opaque magenta. HTML fuchsia is equivalent.
|
||||
*/
|
||||
constexpr SkColor SK_ColorMAGENTA = SkColorSetARGB(0xFF, 0xFF, 0x00, 0xFF);
|
||||
|
||||
/** Converts RGB to its HSV components.
|
||||
hsv[0] contains hsv hue, a value from zero to less than 360.
|
||||
hsv[1] contains hsv saturation, a value from zero to one.
|
||||
hsv[2] contains hsv value, a value from zero to one.
|
||||
|
||||
@param red red component value from zero to 255
|
||||
@param green green component value from zero to 255
|
||||
@param blue blue component value from zero to 255
|
||||
@param hsv three element array which holds the resulting HSV components
|
||||
*/
|
||||
SK_API void SkRGBToHSV(U8CPU red, U8CPU green, U8CPU blue, SkScalar hsv[3]);
|
||||
|
||||
/** Converts ARGB to its HSV components. Alpha in ARGB is ignored.
|
||||
hsv[0] contains hsv hue, and is assigned a value from zero to less than 360.
|
||||
hsv[1] contains hsv saturation, a value from zero to one.
|
||||
hsv[2] contains hsv value, a value from zero to one.
|
||||
|
||||
@param color ARGB color to convert
|
||||
@param hsv three element array which holds the resulting HSV components
|
||||
*/
|
||||
static inline void SkColorToHSV(SkColor color, SkScalar hsv[3]) {
|
||||
SkRGBToHSV(SkColorGetR(color), SkColorGetG(color), SkColorGetB(color), hsv);
|
||||
}
|
||||
|
||||
/** Converts HSV components to an ARGB color. Alpha is passed through unchanged.
|
||||
hsv[0] represents hsv hue, an angle from zero to less than 360.
|
||||
hsv[1] represents hsv saturation, and varies from zero to one.
|
||||
hsv[2] represents hsv value, and varies from zero to one.
|
||||
|
||||
Out of range hsv values are pinned.
|
||||
|
||||
@param alpha alpha component of the returned ARGB color
|
||||
@param hsv three element array which holds the input HSV components
|
||||
@return ARGB equivalent to HSV
|
||||
*/
|
||||
SK_API SkColor SkHSVToColor(U8CPU alpha, const SkScalar hsv[3]);
|
||||
|
||||
/** Converts HSV components to an ARGB color. Alpha is set to 255.
|
||||
hsv[0] represents hsv hue, an angle from zero to less than 360.
|
||||
hsv[1] represents hsv saturation, and varies from zero to one.
|
||||
hsv[2] represents hsv value, and varies from zero to one.
|
||||
|
||||
Out of range hsv values are pinned.
|
||||
|
||||
@param hsv three element array which holds the input HSV components
|
||||
@return RGB equivalent to HSV
|
||||
*/
|
||||
static inline SkColor SkHSVToColor(const SkScalar hsv[3]) {
|
||||
return SkHSVToColor(0xFF, hsv);
|
||||
}
|
||||
|
||||
/** 32-bit ARGB color value, premultiplied. The byte order for this value is
|
||||
configuration dependent, matching the format of kBGRA_8888_SkColorType bitmaps.
|
||||
This is different from SkColor, which is unpremultiplied, and is always in the
|
||||
same byte order.
|
||||
*/
|
||||
typedef uint32_t SkPMColor;
|
||||
|
||||
/** Returns a SkPMColor value from unpremultiplied 8-bit component values.
|
||||
|
||||
@param a amount of alpha, from fully transparent (0) to fully opaque (255)
|
||||
@param r amount of red, from no red (0) to full red (255)
|
||||
@param g amount of green, from no green (0) to full green (255)
|
||||
@param b amount of blue, from no blue (0) to full blue (255)
|
||||
@return premultiplied color
|
||||
*/
|
||||
SK_API SkPMColor SkPreMultiplyARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b);
|
||||
|
||||
/** Returns pmcolor closest to color c. Multiplies c RGB components by the c alpha,
|
||||
and arranges the bytes to match the format of kN32_SkColorType.
|
||||
|
||||
@param c unpremultiplied ARGB color
|
||||
@return premultiplied color
|
||||
*/
|
||||
SK_API SkPMColor SkPreMultiplyColor(SkColor c);
|
||||
|
||||
/** \enum SkColorChannel
|
||||
Describes different color channels one can manipulate
|
||||
*/
|
||||
enum class SkColorChannel {
|
||||
kR, // the red channel
|
||||
kG, // the green channel
|
||||
kB, // the blue channel
|
||||
kA, // the alpha channel
|
||||
|
||||
kLastEnum = kA,
|
||||
};
|
||||
|
||||
/** Used to represent the channels available in a color type or texture format as a mask. */
|
||||
enum SkColorChannelFlag : uint32_t {
|
||||
kRed_SkColorChannelFlag = 1 << static_cast<uint32_t>(SkColorChannel::kR),
|
||||
kGreen_SkColorChannelFlag = 1 << static_cast<uint32_t>(SkColorChannel::kG),
|
||||
kBlue_SkColorChannelFlag = 1 << static_cast<uint32_t>(SkColorChannel::kB),
|
||||
kAlpha_SkColorChannelFlag = 1 << static_cast<uint32_t>(SkColorChannel::kA),
|
||||
kGray_SkColorChannelFlag = 0x10,
|
||||
// Convenience values
|
||||
kGrayAlpha_SkColorChannelFlags = kGray_SkColorChannelFlag | kAlpha_SkColorChannelFlag,
|
||||
kRG_SkColorChannelFlags = kRed_SkColorChannelFlag | kGreen_SkColorChannelFlag,
|
||||
kRGB_SkColorChannelFlags = kRG_SkColorChannelFlags | kBlue_SkColorChannelFlag,
|
||||
kRGBA_SkColorChannelFlags = kRGB_SkColorChannelFlags | kAlpha_SkColorChannelFlag,
|
||||
};
|
||||
static_assert(0 == (kGray_SkColorChannelFlag & kRGBA_SkColorChannelFlags), "bitfield conflict");
|
||||
|
||||
/** \struct SkRGBA4f
|
||||
RGBA color value, holding four floating point components. Color components are always in
|
||||
a known order. kAT determines if the SkRGBA4f's R, G, and B components are premultiplied
|
||||
by alpha or not.
|
||||
|
||||
Skia's public API always uses unpremultiplied colors, which can be stored as
|
||||
SkRGBA4f<kUnpremul_SkAlphaType>. For convenience, this type can also be referred to
|
||||
as SkColor4f.
|
||||
*/
|
||||
template <SkAlphaType kAT>
|
||||
struct SkRGBA4f {
|
||||
float fR; //!< red component
|
||||
float fG; //!< green component
|
||||
float fB; //!< blue component
|
||||
float fA; //!< alpha component
|
||||
|
||||
/** Compares SkRGBA4f with other, and returns true if all components are equal.
|
||||
|
||||
@param other SkRGBA4f to compare
|
||||
@return true if SkRGBA4f equals other
|
||||
*/
|
||||
bool operator==(const SkRGBA4f& other) const {
|
||||
return fA == other.fA && fR == other.fR && fG == other.fG && fB == other.fB;
|
||||
}
|
||||
|
||||
/** Compares SkRGBA4f with other, and returns true if not all components are equal.
|
||||
|
||||
@param other SkRGBA4f to compare
|
||||
@return true if SkRGBA4f is not equal to other
|
||||
*/
|
||||
bool operator!=(const SkRGBA4f& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
/** Returns SkRGBA4f multiplied by scale.
|
||||
|
||||
@param scale value to multiply by
|
||||
@return SkRGBA4f as (fR * scale, fG * scale, fB * scale, fA * scale)
|
||||
*/
|
||||
SkRGBA4f operator*(float scale) const {
|
||||
return { fR * scale, fG * scale, fB * scale, fA * scale };
|
||||
}
|
||||
|
||||
/** Returns SkRGBA4f multiplied component-wise by scale.
|
||||
|
||||
@param scale SkRGBA4f to multiply by
|
||||
@return SkRGBA4f as (fR * scale.fR, fG * scale.fG, fB * scale.fB, fA * scale.fA)
|
||||
*/
|
||||
SkRGBA4f operator*(const SkRGBA4f& scale) const {
|
||||
return { fR * scale.fR, fG * scale.fG, fB * scale.fB, fA * scale.fA };
|
||||
}
|
||||
|
||||
/** Returns a pointer to components of SkRGBA4f, for array access.
|
||||
|
||||
@return pointer to array [fR, fG, fB, fA]
|
||||
*/
|
||||
const float* vec() const { return &fR; }
|
||||
|
||||
/** Returns a pointer to components of SkRGBA4f, for array access.
|
||||
|
||||
@return pointer to array [fR, fG, fB, fA]
|
||||
*/
|
||||
float* vec() { return &fR; }
|
||||
|
||||
/** As a std::array<float, 4> */
|
||||
std::array<float, 4> array() const { return {fR, fG, fB, fA}; }
|
||||
|
||||
/** Returns one component. Asserts if index is out of range and SK_DEBUG is defined.
|
||||
|
||||
@param index one of: 0 (fR), 1 (fG), 2 (fB), 3 (fA)
|
||||
@return value corresponding to index
|
||||
*/
|
||||
float operator[](int index) const {
|
||||
SkASSERT(index >= 0 && index < 4);
|
||||
return this->vec()[index];
|
||||
}
|
||||
|
||||
/** Returns one component. Asserts if index is out of range and SK_DEBUG is defined.
|
||||
|
||||
@param index one of: 0 (fR), 1 (fG), 2 (fB), 3 (fA)
|
||||
@return value corresponding to index
|
||||
*/
|
||||
float& operator[](int index) {
|
||||
SkASSERT(index >= 0 && index < 4);
|
||||
return this->vec()[index];
|
||||
}
|
||||
|
||||
/** Returns true if SkRGBA4f is an opaque color. Asserts if fA is out of range and
|
||||
SK_DEBUG is defined.
|
||||
|
||||
@return true if SkRGBA4f is opaque
|
||||
*/
|
||||
bool isOpaque() const {
|
||||
SkASSERT(fA <= 1.0f && fA >= 0.0f);
|
||||
return fA == 1.0f;
|
||||
}
|
||||
|
||||
/** Returns true if all channels are in [0, 1]. */
|
||||
bool fitsInBytes() const {
|
||||
SkASSERT(fA >= 0.0f && fA <= 1.0f);
|
||||
return fR >= 0.0f && fR <= 1.0f &&
|
||||
fG >= 0.0f && fG <= 1.0f &&
|
||||
fB >= 0.0f && fB <= 1.0f;
|
||||
}
|
||||
|
||||
/** Returns closest SkRGBA4f to SkColor. Only allowed if SkRGBA4f is unpremultiplied.
|
||||
|
||||
@param color Color with Alpha, red, blue, and green components
|
||||
@return SkColor as SkRGBA4f
|
||||
|
||||
example: https://fiddle.skia.org/c/@RGBA4f_FromColor
|
||||
*/
|
||||
static SkRGBA4f FromColor(SkColor color); // impl. depends on kAT
|
||||
|
||||
/** Returns closest SkColor to SkRGBA4f. Only allowed if SkRGBA4f is unpremultiplied.
|
||||
|
||||
@return color as SkColor
|
||||
|
||||
example: https://fiddle.skia.org/c/@RGBA4f_toSkColor
|
||||
*/
|
||||
SkColor toSkColor() const; // impl. depends on kAT
|
||||
|
||||
/** Returns closest SkRGBA4f to SkPMColor. Only allowed if SkRGBA4f is premultiplied.
|
||||
|
||||
@return SkPMColor as SkRGBA4f
|
||||
*/
|
||||
static SkRGBA4f FromPMColor(SkPMColor); // impl. depends on kAT
|
||||
|
||||
/** Returns SkRGBA4f premultiplied by alpha. Asserts at compile time if SkRGBA4f is
|
||||
already premultiplied.
|
||||
|
||||
@return premultiplied color
|
||||
*/
|
||||
SkRGBA4f<kPremul_SkAlphaType> premul() const {
|
||||
static_assert(kAT == kUnpremul_SkAlphaType, "");
|
||||
return { fR * fA, fG * fA, fB * fA, fA };
|
||||
}
|
||||
|
||||
/** Returns SkRGBA4f unpremultiplied by alpha. Asserts at compile time if SkRGBA4f is
|
||||
already unpremultiplied.
|
||||
|
||||
@return unpremultiplied color
|
||||
*/
|
||||
SkRGBA4f<kUnpremul_SkAlphaType> unpremul() const {
|
||||
static_assert(kAT == kPremul_SkAlphaType, "");
|
||||
|
||||
if (fA == 0.0f) {
|
||||
return { 0, 0, 0, 0 };
|
||||
} else {
|
||||
float invAlpha = 1 / fA;
|
||||
return { fR * invAlpha, fG * invAlpha, fB * invAlpha, fA };
|
||||
}
|
||||
}
|
||||
|
||||
// This produces bytes in RGBA order (eg GrColor). Impl. is the same, regardless of kAT
|
||||
uint32_t toBytes_RGBA() const;
|
||||
static SkRGBA4f FromBytes_RGBA(uint32_t color);
|
||||
|
||||
/**
|
||||
Returns a copy of the SkRGBA4f but with alpha component set to 1.0f.
|
||||
|
||||
@return opaque color
|
||||
*/
|
||||
SkRGBA4f makeOpaque() const {
|
||||
return { fR, fG, fB, 1.0f };
|
||||
}
|
||||
|
||||
/**
|
||||
Returns a copy of the SkRGBA4f but with the alpha component pinned to [0, 1].
|
||||
|
||||
@return color with pinned alpha
|
||||
*/
|
||||
SkRGBA4f pinAlpha() const {
|
||||
return { fR, fG, fB, SkTPin(fA, 0.f, 1.f) };
|
||||
}
|
||||
|
||||
/** Returns this color, having replaced its alpha value.
|
||||
*/
|
||||
SkRGBA4f withAlpha(float a) const {
|
||||
return { fR, fG, fB, a };
|
||||
}
|
||||
|
||||
/** Returns this color, having replaced its alpha value specified as a byte.
|
||||
*/
|
||||
SkRGBA4f withAlphaByte(uint8_t a) const {
|
||||
return { fR, fG, fB, a/255.f };
|
||||
}
|
||||
};
|
||||
|
||||
/** \struct SkColor4f
|
||||
RGBA color value, holding four floating point components. Color components are always in
|
||||
a known order, and are unpremultiplied.
|
||||
|
||||
This is a specialization of SkRGBA4f. For details, @see SkRGBA4f.
|
||||
*/
|
||||
using SkColor4f = SkRGBA4f<kUnpremul_SkAlphaType>;
|
||||
|
||||
template <> SK_API SkColor4f SkColor4f::FromColor(SkColor);
|
||||
template <> SK_API SkColor SkColor4f::toSkColor() const;
|
||||
template <> SK_API uint32_t SkColor4f::toBytes_RGBA() const;
|
||||
template <> SK_API SkColor4f SkColor4f::FromBytes_RGBA(uint32_t color);
|
||||
|
||||
namespace SkColors {
|
||||
constexpr SkColor4f kTransparent = {0, 0, 0, 0};
|
||||
constexpr SkColor4f kBlack = {0, 0, 0, 1};
|
||||
constexpr SkColor4f kDkGray = {0.25f, 0.25f, 0.25f, 1};
|
||||
constexpr SkColor4f kGray = {0.50f, 0.50f, 0.50f, 1};
|
||||
constexpr SkColor4f kLtGray = {0.75f, 0.75f, 0.75f, 1};
|
||||
constexpr SkColor4f kWhite = {1, 1, 1, 1};
|
||||
constexpr SkColor4f kRed = {1, 0, 0, 1};
|
||||
constexpr SkColor4f kGreen = {0, 1, 0, 1};
|
||||
constexpr SkColor4f kBlue = {0, 0, 1, 1};
|
||||
constexpr SkColor4f kYellow = {1, 1, 0, 1};
|
||||
constexpr SkColor4f kCyan = {0, 1, 1, 1};
|
||||
constexpr SkColor4f kMagenta = {1, 0, 1, 1};
|
||||
} // namespace SkColors
|
||||
#endif
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* 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 SkColorFilter_DEFINED
|
||||
#define SkColorFilter_DEFINED
|
||||
|
||||
#include "include/core/SkColor.h"
|
||||
#include "include/core/SkFlattenable.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/private/base/SkAPI.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
|
||||
class SkColorMatrix;
|
||||
class SkColorSpace;
|
||||
class SkColorTable;
|
||||
|
||||
enum class SkBlendMode;
|
||||
struct SkDeserialProcs;
|
||||
|
||||
/**
|
||||
* ColorFilters are optional objects in the drawing pipeline. When present in
|
||||
* a paint, they are called with the "src" colors, and return new colors, which
|
||||
* are then passed onto the next stage (either ImageFilter or Xfermode).
|
||||
*
|
||||
* All subclasses are required to be reentrant-safe : it must be legal to share
|
||||
* the same instance between several threads.
|
||||
*/
|
||||
class SK_API SkColorFilter : public SkFlattenable {
|
||||
public:
|
||||
/** If the filter can be represented by a source color plus Mode, this
|
||||
* returns true, and sets (if not NULL) the color and mode appropriately.
|
||||
* If not, this returns false and ignores the parameters.
|
||||
*/
|
||||
bool asAColorMode(SkColor* color, SkBlendMode* mode) const;
|
||||
|
||||
/** If the filter can be represented by a 5x4 matrix, this
|
||||
* returns true, and sets the matrix appropriately.
|
||||
* If not, this returns false and ignores the parameter.
|
||||
*/
|
||||
bool asAColorMatrix(float matrix[20]) const;
|
||||
|
||||
// Returns true if the filter is guaranteed to never change the alpha of a color it filters.
|
||||
bool isAlphaUnchanged() const;
|
||||
|
||||
/**
|
||||
* Converts the src color (in src colorspace), into the dst colorspace,
|
||||
* then applies this filter to it, returning the filtered color in the dst colorspace.
|
||||
*/
|
||||
SkColor4f filterColor4f(const SkColor4f& srcColor, SkColorSpace* srcCS,
|
||||
SkColorSpace* dstCS) const;
|
||||
|
||||
/** Construct a colorfilter whose effect is to first apply the inner filter and then apply
|
||||
* this filter, applied to the output of the inner filter.
|
||||
*
|
||||
* result = this(inner(...))
|
||||
*/
|
||||
sk_sp<SkColorFilter> makeComposed(sk_sp<SkColorFilter> inner) const;
|
||||
|
||||
/** Return a colorfilter that will compute this filter in a specific color space. By default all
|
||||
* filters operate in the destination (surface) color space. This allows filters like Blend and
|
||||
* Matrix, or runtime color filters to perform their math in a known space.
|
||||
*/
|
||||
sk_sp<SkColorFilter> makeWithWorkingColorSpace(sk_sp<SkColorSpace>) const;
|
||||
|
||||
static sk_sp<SkColorFilter> Deserialize(const void* data, size_t size,
|
||||
const SkDeserialProcs* procs = nullptr);
|
||||
|
||||
private:
|
||||
SkColorFilter() = default;
|
||||
friend class SkColorFilterBase;
|
||||
|
||||
using INHERITED = SkFlattenable;
|
||||
};
|
||||
|
||||
class SK_API SkColorFilters {
|
||||
public:
|
||||
static sk_sp<SkColorFilter> Compose(const sk_sp<SkColorFilter>& outer,
|
||||
sk_sp<SkColorFilter> inner) {
|
||||
return outer ? outer->makeComposed(std::move(inner))
|
||||
: std::move(inner);
|
||||
}
|
||||
|
||||
// Blends between the constant color (src) and input color (dst) based on the SkBlendMode.
|
||||
// If the color space is null, the constant color is assumed to be defined in sRGB.
|
||||
static sk_sp<SkColorFilter> Blend(const SkColor4f& c, sk_sp<SkColorSpace>, SkBlendMode mode);
|
||||
static sk_sp<SkColorFilter> Blend(SkColor c, SkBlendMode mode);
|
||||
|
||||
enum class Clamp : bool { kNo, kYes };
|
||||
|
||||
static sk_sp<SkColorFilter> Matrix(const SkColorMatrix&, Clamp clamp = Clamp::kYes);
|
||||
static sk_sp<SkColorFilter> Matrix(const float rowMajor[20], Clamp clamp = Clamp::kYes);
|
||||
|
||||
// A version of Matrix which operates in HSLA space instead of RGBA.
|
||||
// I.e. HSLA-to-RGBA(Matrix(RGBA-to-HSLA(input))).
|
||||
static sk_sp<SkColorFilter> HSLAMatrix(const SkColorMatrix&);
|
||||
static sk_sp<SkColorFilter> HSLAMatrix(const float rowMajor[20]);
|
||||
|
||||
static sk_sp<SkColorFilter> LinearToSRGBGamma();
|
||||
static sk_sp<SkColorFilter> SRGBToLinearGamma();
|
||||
static sk_sp<SkColorFilter> Lerp(float t, sk_sp<SkColorFilter> dst, sk_sp<SkColorFilter> src);
|
||||
|
||||
/**
|
||||
* Create a table colorfilter, copying the table into the filter, and
|
||||
* applying it to all 4 components.
|
||||
* a' = table[a];
|
||||
* r' = table[r];
|
||||
* g' = table[g];
|
||||
* b' = table[b];
|
||||
* Components are operated on in unpremultiplied space. If the incomming
|
||||
* colors are premultiplied, they are temporarily unpremultiplied, then
|
||||
* the table is applied, and then the result is remultiplied.
|
||||
*/
|
||||
static sk_sp<SkColorFilter> Table(const uint8_t table[256]);
|
||||
|
||||
/**
|
||||
* Create a table colorfilter, with a different table for each
|
||||
* component [A, R, G, B]. If a given table is NULL, then it is
|
||||
* treated as identity, with the component left unchanged. If a table
|
||||
* is not null, then its contents are copied into the filter.
|
||||
*/
|
||||
static sk_sp<SkColorFilter> TableARGB(const uint8_t tableA[256],
|
||||
const uint8_t tableR[256],
|
||||
const uint8_t tableG[256],
|
||||
const uint8_t tableB[256]);
|
||||
|
||||
/**
|
||||
* Create a table colorfilter that holds a ref to the shared color table.
|
||||
*/
|
||||
static sk_sp<SkColorFilter> Table(sk_sp<SkColorTable> table);
|
||||
|
||||
/**
|
||||
* Create a colorfilter that multiplies the RGB channels by one color, and
|
||||
* then adds a second color, pinning the result for each component to
|
||||
* [0..255]. The alpha components of the mul and add arguments
|
||||
* are ignored.
|
||||
*/
|
||||
static sk_sp<SkColorFilter> Lighting(SkColor mul, SkColor add);
|
||||
|
||||
private:
|
||||
SkColorFilters() = delete;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,432 @@
|
|||
/*
|
||||
* 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 "include/core/SkRefCnt.h"
|
||||
#include "include/core/SkTypes.h"
|
||||
#include "include/private/base/SkFixed.h"
|
||||
#include "include/private/base/SkOnce.h"
|
||||
#include "modules/skcms/skcms.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
class SkData;
|
||||
|
||||
/**
|
||||
* Describes a color gamut with primaries and a white point.
|
||||
*/
|
||||
struct SK_API SkColorSpacePrimaries {
|
||||
float fRX;
|
||||
float fRY;
|
||||
float fGX;
|
||||
float fGY;
|
||||
float fBX;
|
||||
float fBY;
|
||||
float fWX;
|
||||
float fWY;
|
||||
|
||||
/**
|
||||
* Convert primaries and a white point to a toXYZD50 matrix, the preferred color gamut
|
||||
* representation of SkColorSpace.
|
||||
*/
|
||||
bool toXYZD50(skcms_Matrix3x3* toXYZD50) const;
|
||||
|
||||
bool operator==(const SkColorSpacePrimaries& other) const {
|
||||
return fRX == other.fRX && fRY == other.fRY && fGX == other.fGX && fGY == other.fGY &&
|
||||
fBX == other.fBX && fBY == other.fBY && fWX == other.fWX && fWY == other.fWY;
|
||||
}
|
||||
};
|
||||
|
||||
// TODO(https://issuetracker.google.com/issues/40044808): Remove this when no longer needed by
|
||||
// Chromium.
|
||||
#define SKIA_COLOR_SPACE_PRIMARIES_OPERATOR_EQUAL
|
||||
|
||||
namespace SkNamedPrimaries {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Color primaries defined by ITU-T H.273, table 2. Names are given by the first
|
||||
// specification referenced in the value's row.
|
||||
|
||||
// Rec. ITU-R BT.709-6, value 1.
|
||||
static constexpr SkColorSpacePrimaries kRec709 = {
|
||||
0.64f, 0.33f, 0.3f, 0.6f, 0.15f, 0.06f, 0.3127f, 0.329f};
|
||||
|
||||
// Rec. ITU-R BT.470-6 System M (historical), value 4.
|
||||
static constexpr SkColorSpacePrimaries kRec470SystemM = {
|
||||
0.67f, 0.33f, 0.21f, 0.71f, 0.14f, 0.08f, 0.31f, 0.316f};
|
||||
|
||||
// Rec. ITU-R BT.470-6 System B, G (historical), value 5.
|
||||
static constexpr SkColorSpacePrimaries kRec470SystemBG = {
|
||||
0.64f, 0.33f, 0.29f, 0.60f, 0.15f, 0.06f, 0.3127f, 0.3290f};
|
||||
|
||||
// Rec. ITU-R BT.601-7 525, value 6.
|
||||
static constexpr SkColorSpacePrimaries kRec601 = {
|
||||
0.630f, 0.340f, 0.310f, 0.595f, 0.155f, 0.070f, 0.3127f, 0.3290f};
|
||||
|
||||
// SMPTE ST 240, value 7 (functionally the same as value 6).
|
||||
static constexpr SkColorSpacePrimaries kSMPTE_ST_240 = kRec601;
|
||||
|
||||
// Generic film (colour filters using Illuminant C), value 8.
|
||||
static constexpr SkColorSpacePrimaries kGenericFilm = {
|
||||
0.681f, 0.319f, 0.243f, 0.692f, 0.145f, 0.049f, 0.310f, 0.316f};
|
||||
|
||||
// Rec. ITU-R BT.2020-2, value 9.
|
||||
static constexpr SkColorSpacePrimaries kRec2020{
|
||||
0.708f, 0.292f, 0.170f, 0.797f, 0.131f, 0.046f, 0.3127f, 0.3290f};
|
||||
|
||||
// SMPTE ST 428-1, value 10.
|
||||
static constexpr SkColorSpacePrimaries kSMPTE_ST_428_1 = {
|
||||
1.f, 0.f, 0.f, 1.f, 0.f, 0.f, 1.f / 3.f, 1.f / 3.f};
|
||||
|
||||
// SMPTE RP 431-2, value 11.
|
||||
static constexpr SkColorSpacePrimaries kSMPTE_RP_431_2 = {
|
||||
0.680f, 0.320f, 0.265f, 0.690f, 0.150f, 0.060f, 0.314f, 0.351f};
|
||||
|
||||
// SMPTE EG 432-1, value 12.
|
||||
static constexpr SkColorSpacePrimaries kSMPTE_EG_432_1 = {
|
||||
0.680f, 0.320f, 0.265f, 0.690f, 0.150f, 0.060f, 0.3127f, 0.3290f};
|
||||
|
||||
// No corresponding industry specification identified, value 22.
|
||||
// This is sometimes referred to as EBU 3213-E, but that document doesn't
|
||||
// specify these values.
|
||||
static constexpr SkColorSpacePrimaries kITU_T_H273_Value22 = {
|
||||
0.630f, 0.340f, 0.295f, 0.605f, 0.155f, 0.077f, 0.3127f, 0.3290f};
|
||||
|
||||
// Mapping between names of color primaries and the number of the corresponding
|
||||
// row in ITU-T H.273, table 2. As above, the constants are named based on the
|
||||
// first specification referenced in the value's row.
|
||||
enum class CicpId : uint8_t {
|
||||
// Value 0 is reserved.
|
||||
kRec709 = 1,
|
||||
// Value 2 is unspecified.
|
||||
// Value 3 is reserved.
|
||||
kRec470SystemM = 4,
|
||||
kRec470SystemBG = 5,
|
||||
kRec601 = 6,
|
||||
kSMPTE_ST_240 = 7,
|
||||
kGenericFilm = 8,
|
||||
kRec2020 = 9,
|
||||
kSMPTE_ST_428_1 = 10,
|
||||
kSMPTE_RP_431_2 = 11,
|
||||
kSMPTE_EG_432_1 = 12,
|
||||
// Values 13-21 are reserved.
|
||||
kITU_T_H273_Value22 = 22,
|
||||
// Values 23-255 are reserved.
|
||||
};
|
||||
|
||||
// https://www.w3.org/TR/css-color-4/#predefined-prophoto-rgb
|
||||
static constexpr SkColorSpacePrimaries kProPhotoRGB = {
|
||||
0.7347f, 0.2653f, 0.1596f, 0.8404f, 0.0366f, 0.0001f, 0.34567f, 0.35850f};
|
||||
|
||||
} // namespace SkNamedPrimaries
|
||||
|
||||
namespace SkNamedTransferFn {
|
||||
|
||||
// Like SkNamedGamut::kSRGB, keeping this bitwise exactly the same as skcms makes things fastest.
|
||||
static constexpr skcms_TransferFunction kSRGB =
|
||||
{ 2.4f, (float)(1/1.055), (float)(0.055/1.055), (float)(1/12.92), 0.04045f, 0.0f, 0.0f };
|
||||
|
||||
static constexpr skcms_TransferFunction k2Dot2 =
|
||||
{ 2.2f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
|
||||
static constexpr skcms_TransferFunction kRec2020 = {
|
||||
2.22222f, 0.909672f, 0.0903276f, 0.222222f, 0.0812429f, 0, 0};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Transfer function defined by ITU-T H.273, table 3. Names are given by the
|
||||
// first specification referenced in the value's row. The equations in table 3
|
||||
// "either indicates the reference [OETF] ... or indicates the inverse of the
|
||||
// reference EOTF". The transfer functions provided are reference EOTFs.
|
||||
|
||||
// Rec. ITU-R BT.709-6, value 1. This follows note 1, which reads: "In the cases
|
||||
// of [...] TransferCharacteristics equal to 1, 6, 14 or 15 [...], although the
|
||||
// value is defined in terms of a reference [OETF], a suggested corresponding
|
||||
// reference [EOTF] has been specified in Rec. ITU-R BT.1886-0."
|
||||
static constexpr skcms_TransferFunction kRec709 = {2.4f, 1.f, 0.f, 0.f, 0.f, 0.f, 0.f};
|
||||
|
||||
// Rec. ITU-R BT.470-6 System M (historical) assumed display gamma 2.2, value 4.
|
||||
static constexpr skcms_TransferFunction kRec470SystemM = {2.2f, 1.f, 0.f, 0.f, 0.f, 0.f, 0.f};
|
||||
|
||||
// Rec. ITU-R BT.470-6 System B, G (historical) assumed display gamma 2.8,
|
||||
// value 5.
|
||||
static constexpr skcms_TransferFunction kRec470SystemBG = {2.8f, 1.f, 0.f, 0.f, 0.f, 0.f, 0.f};
|
||||
|
||||
// Rec. ITU-R BT.601-7, same as kRec709, value 6.
|
||||
static constexpr skcms_TransferFunction kRec601 = kRec709;
|
||||
|
||||
// SMPTE ST 240, value 7.
|
||||
static constexpr skcms_TransferFunction kSMPTE_ST_240 = {
|
||||
2.222222222222f, 0.899626676224f, 0.100373323776f, 0.25f, 0.091286342118f, 0.f, 0.f};
|
||||
|
||||
// Linear, value 8
|
||||
static constexpr skcms_TransferFunction kLinear =
|
||||
{ 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
|
||||
// IEC 61966-2-4, value 11, same as kRec709 (but is explicitly extended).
|
||||
static constexpr skcms_TransferFunction kIEC61966_2_4 = kRec709;
|
||||
|
||||
// IEC 61966-2-1 sRGB, value 13.
|
||||
static constexpr skcms_TransferFunction kIEC61966_2_1 = kSRGB;
|
||||
|
||||
// Rec. ITU-R BT.2020-2 (10-bit system), value 14.
|
||||
static constexpr skcms_TransferFunction kRec2020_10bit = kRec709;
|
||||
|
||||
// Rec. ITU-R BT.2020-2 (12-bit system), value 15.
|
||||
static constexpr skcms_TransferFunction kRec2020_12bit = kRec709;
|
||||
|
||||
// Rec. ITU-R BT.2100-2 perceptual quantization (PQ) system, value 16.
|
||||
static constexpr skcms_TransferFunction kPQ =
|
||||
{-5.0f, 203.f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
|
||||
// SMPTE ST 428-1, value 17.
|
||||
static constexpr skcms_TransferFunction kSMPTE_ST_428_1 = {
|
||||
2.6f, 1.034080527699f, 0.f, 0.f, 0.f, 0.f, 0.f};
|
||||
|
||||
// Rec. ITU-R BT.2100-2 hybrid log-gamma (HLG) system, value 18.
|
||||
static constexpr skcms_TransferFunction kHLG =
|
||||
{-6.0f, 203.f, 1000.0f, 1.2f, 0.0f, 0.0f, 0.0f };
|
||||
|
||||
// Mapping between transfer function names and the number of the corresponding
|
||||
// row in ITU-T H.273, table 3. As above, the constants are named based on the
|
||||
// first specification referenced in the value's row.
|
||||
enum class CicpId : uint8_t {
|
||||
// Value 0 is reserved.
|
||||
kRec709 = 1,
|
||||
// Value 2 is unspecified.
|
||||
// Value 3 is reserved.
|
||||
kRec470SystemM = 4,
|
||||
kRec470SystemBG = 5,
|
||||
kRec601 = 6,
|
||||
kSMPTE_ST_240 = 7,
|
||||
kLinear = 8,
|
||||
// Value 9 is not supported by `SkColorSpace::MakeCICP`.
|
||||
// Value 10 is not supported by `SkColorSpace::MakeCICP`.
|
||||
kIEC61966_2_4 = 11,
|
||||
// Value 12 is not supported by `SkColorSpace::MakeCICP`.
|
||||
kIEC61966_2_1 = 13,
|
||||
kSRGB = kIEC61966_2_1,
|
||||
kRec2020_10bit = 14,
|
||||
kRec2020_12bit = 15,
|
||||
kPQ = 16,
|
||||
kSMPTE_ST_428_1 = 17,
|
||||
kHLG = 18,
|
||||
// Values 19-255 are reserved.
|
||||
};
|
||||
|
||||
// https://w3.org/TR/css-color-4/#valdef-color-prophoto-rgb
|
||||
// "The transfer curve is a gamma function with a value of 1/1.8"
|
||||
static constexpr skcms_TransferFunction kProPhotoRGB = {1.8f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
|
||||
|
||||
// https://www.w3.org/TR/css-color-4/#predefined-a98-rgb
|
||||
static constexpr skcms_TransferFunction kA98RGB = k2Dot2;
|
||||
|
||||
} // namespace SkNamedTransferFn
|
||||
|
||||
namespace SkNamedGamut {
|
||||
|
||||
static constexpr skcms_Matrix3x3 kSRGB = {{
|
||||
// ICC fixed-point (16.16) representation, taken from skcms. Please keep them exactly in sync.
|
||||
// 0.436065674f, 0.385147095f, 0.143066406f,
|
||||
// 0.222488403f, 0.716873169f, 0.060607910f,
|
||||
// 0.013916016f, 0.097076416f, 0.714096069f,
|
||||
{ SkFixedToFloat(0x6FA2), SkFixedToFloat(0x6299), SkFixedToFloat(0x24A0) },
|
||||
{ SkFixedToFloat(0x38F5), SkFixedToFloat(0xB785), SkFixedToFloat(0x0F84) },
|
||||
{ SkFixedToFloat(0x0390), SkFixedToFloat(0x18DA), SkFixedToFloat(0xB6CF) },
|
||||
}};
|
||||
|
||||
static constexpr skcms_Matrix3x3 kAdobeRGB = {{
|
||||
// ICC fixed-point (16.16) repesentation of:
|
||||
// 0.60974, 0.20528, 0.14919,
|
||||
// 0.31111, 0.62567, 0.06322,
|
||||
// 0.01947, 0.06087, 0.74457,
|
||||
{ SkFixedToFloat(0x9c18), SkFixedToFloat(0x348d), SkFixedToFloat(0x2631) },
|
||||
{ SkFixedToFloat(0x4fa5), SkFixedToFloat(0xa02c), SkFixedToFloat(0x102f) },
|
||||
{ SkFixedToFloat(0x04fc), SkFixedToFloat(0x0f95), SkFixedToFloat(0xbe9c) },
|
||||
}};
|
||||
|
||||
static constexpr skcms_Matrix3x3 kDisplayP3 = {{
|
||||
{ 0.515102f, 0.291965f, 0.157153f },
|
||||
{ 0.241182f, 0.692236f, 0.0665819f },
|
||||
{ -0.00104941f, 0.0418818f, 0.784378f },
|
||||
}};
|
||||
|
||||
static constexpr skcms_Matrix3x3 kRec2020 = {{
|
||||
{ 0.673459f, 0.165661f, 0.125100f },
|
||||
{ 0.279033f, 0.675338f, 0.0456288f },
|
||||
{ -0.00193139f, 0.0299794f, 0.797162f },
|
||||
}};
|
||||
|
||||
static constexpr skcms_Matrix3x3 kXYZ = {{
|
||||
{ 1.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 1.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 1.0f },
|
||||
}};
|
||||
|
||||
} // namespace SkNamedGamut
|
||||
|
||||
class SK_API SkColorSpace : public SkNVRefCnt<SkColorSpace> {
|
||||
public:
|
||||
/**
|
||||
* Create the sRGB color space.
|
||||
*/
|
||||
static sk_sp<SkColorSpace> MakeSRGB();
|
||||
|
||||
/**
|
||||
* Colorspace with the sRGB primaries, but a linear (1.0) gamma.
|
||||
*/
|
||||
static sk_sp<SkColorSpace> MakeSRGBLinear();
|
||||
|
||||
/**
|
||||
* Create an SkColorSpace from a transfer function and a row-major 3x3 transformation to XYZ.
|
||||
*/
|
||||
static sk_sp<SkColorSpace> MakeRGB(const skcms_TransferFunction& transferFn,
|
||||
const skcms_Matrix3x3& toXYZ);
|
||||
|
||||
/**
|
||||
* Create an SkColorSpace from code points specified in Rec. ITU-T H.273.
|
||||
* Null will be returned for invalid or unsupported combination of code
|
||||
* points.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* - `color_primaries` identifies an entry in Rec. ITU-T H.273, Table 2.
|
||||
* - `transfer_characteristics` identifies an entry in Rec. ITU-T H.273, Table 3.
|
||||
*
|
||||
* `SkColorSpace` (and the underlying `skcms_ICCProfile`) only supports RGB
|
||||
* color spaces and therefore this function does not take a
|
||||
* `matrix_coefficients` parameter - the caller is expected to verify that
|
||||
* `matrix_coefficients` is `0`.
|
||||
*
|
||||
* Narrow range images are extremely rare - see
|
||||
* https://github.com/w3c/png/issues/312#issuecomment-2327349614. Therefore
|
||||
* this function doesn't take a `video_full_range_flag` - the caller is
|
||||
* expected to verify that it is `1` (indicating a full range image).
|
||||
*/
|
||||
static sk_sp<SkColorSpace> MakeCICP(SkNamedPrimaries::CicpId color_primaries,
|
||||
SkNamedTransferFn::CicpId transfer_characteristics);
|
||||
|
||||
/**
|
||||
* Create an SkColorSpace from a parsed (skcms) ICC profile.
|
||||
*/
|
||||
static sk_sp<SkColorSpace> Make(const skcms_ICCProfile&);
|
||||
|
||||
/**
|
||||
* Convert this color space to an skcms ICC profile struct.
|
||||
*/
|
||||
void toProfile(skcms_ICCProfile*) const;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Sets |fn| to the transfer function from this color space. Returns true if the transfer
|
||||
* function can be represented as coefficients to the standard ICC 7-parameter equation.
|
||||
* Returns false otherwise (eg, PQ, HLG).
|
||||
*/
|
||||
bool isNumericalTransferFn(skcms_TransferFunction* fn) const;
|
||||
|
||||
/**
|
||||
* Returns true and sets |toXYZD50|.
|
||||
*/
|
||||
bool toXYZD50(skcms_Matrix3x3* toXYZD50) const;
|
||||
|
||||
/**
|
||||
* Returns a hash of the gamut transformation to XYZ D50. Allows for fast equality checking
|
||||
* of gamuts, at the (very small) risk of collision.
|
||||
*/
|
||||
uint32_t toXYZD50Hash() const { return fToXYZD50Hash; }
|
||||
|
||||
/**
|
||||
* Returns a color space with the same gamut as this one, but with a linear gamma.
|
||||
*/
|
||||
sk_sp<SkColorSpace> makeLinearGamma() const;
|
||||
|
||||
/**
|
||||
* Returns a color space with the same gamut as this one, but with the sRGB transfer
|
||||
* function.
|
||||
*/
|
||||
sk_sp<SkColorSpace> makeSRGBGamma() const;
|
||||
|
||||
/**
|
||||
* Returns a color space with the same transfer function as this one, but with the primary
|
||||
* colors rotated. In other words, this produces a new color space that maps RGB to GBR
|
||||
* (when applied to a source), and maps RGB to BRG (when applied to a destination).
|
||||
*
|
||||
* This is used for testing, to construct color spaces that have severe and testable behavior.
|
||||
*/
|
||||
sk_sp<SkColorSpace> makeColorSpin() const;
|
||||
|
||||
/**
|
||||
* Returns true if the color space is sRGB.
|
||||
* Returns false otherwise.
|
||||
*
|
||||
* This allows a little bit of tolerance, given that we might see small numerical error
|
||||
* in some cases: converting ICC fixed point to float, converting white point to D50,
|
||||
* rounding decisions on transfer function and matrix.
|
||||
*
|
||||
* This does not consider a 2.2f exponential transfer function to be sRGB. While these
|
||||
* functions are similar (and it is sometimes useful to consider them together), this
|
||||
* function checks for logical equality.
|
||||
*/
|
||||
bool isSRGB() const;
|
||||
|
||||
/**
|
||||
* Returns a serialized representation of this color space.
|
||||
*/
|
||||
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*, const SkColorSpace*);
|
||||
|
||||
void transferFn(float gabcdef[7]) const; // DEPRECATED: Remove when webview usage is gone
|
||||
void transferFn(skcms_TransferFunction* fn) const;
|
||||
void invTransferFn(skcms_TransferFunction* fn) const;
|
||||
void gamutTransformTo(const SkColorSpace* dst, skcms_Matrix3x3* src_to_dst) const;
|
||||
|
||||
uint32_t transferFnHash() const { return fTransferFnHash; }
|
||||
uint64_t hash() const { return (uint64_t)fTransferFnHash << 32 | fToXYZD50Hash; }
|
||||
|
||||
private:
|
||||
friend class SkColorSpaceSingletonFactory;
|
||||
|
||||
SkColorSpace(const skcms_TransferFunction& transferFn, const skcms_Matrix3x3& toXYZ);
|
||||
|
||||
void computeLazyDstFields() const;
|
||||
|
||||
uint32_t fTransferFnHash;
|
||||
uint32_t fToXYZD50Hash;
|
||||
|
||||
skcms_TransferFunction fTransferFn;
|
||||
skcms_Matrix3x3 fToXYZD50;
|
||||
|
||||
mutable skcms_TransferFunction fInvTransferFn;
|
||||
mutable skcms_Matrix3x3 fFromXYZD50;
|
||||
mutable SkOnce fLazyDstFieldsOnce;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright 2023 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkColorTable_DEFINED
|
||||
#define SkColorTable_DEFINED
|
||||
|
||||
#include "include/core/SkBitmap.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/private/base/SkAPI.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class SkReadBuffer;
|
||||
class SkWriteBuffer;
|
||||
|
||||
/**
|
||||
* SkColorTable holds the lookup tables for each channel (ARGB) used to define the filter behavior
|
||||
* of `SkColorFilters::Table`, and provides a way to share the table data between client code and
|
||||
* the returned SkColorFilter. Once created, an SkColorTable is immutable.
|
||||
*/
|
||||
class SK_API SkColorTable : public SkRefCnt {
|
||||
public:
|
||||
// Creates a new SkColorTable with 'table' used for all four channels. The table is copied into
|
||||
// the SkColorTable.
|
||||
static sk_sp<SkColorTable> Make(const uint8_t table[256]) {
|
||||
return Make(table, table, table, table);
|
||||
}
|
||||
|
||||
// Creates a new SkColorTable with the per-channel lookup tables. Each non-null table is copied
|
||||
// into the SkColorTable. Null parameters are interpreted as the identity table.
|
||||
static sk_sp<SkColorTable> Make(const uint8_t tableA[256],
|
||||
const uint8_t tableR[256],
|
||||
const uint8_t tableG[256],
|
||||
const uint8_t tableB[256]);
|
||||
|
||||
// Per-channel constant value lookup (0-255).
|
||||
const uint8_t* alphaTable() const { return fTable.getAddr8(0, 0); }
|
||||
const uint8_t* redTable() const { return fTable.getAddr8(0, 1); }
|
||||
const uint8_t* greenTable() const { return fTable.getAddr8(0, 2); }
|
||||
const uint8_t* blueTable() const { return fTable.getAddr8(0, 3); }
|
||||
|
||||
void flatten(SkWriteBuffer& buffer) const;
|
||||
|
||||
static sk_sp<SkColorTable> Deserialize(SkReadBuffer& buffer);
|
||||
|
||||
private:
|
||||
friend class SkTableColorFilter; // for bitmap()
|
||||
|
||||
explicit SkColorTable(const SkBitmap& table) : fTable(table) {}
|
||||
|
||||
// The returned SkBitmap is immutable; attempting to modify its pixel data will trigger asserts
|
||||
// in debug builds and cause undefined behavior in release builds.
|
||||
const SkBitmap& bitmap() const { return fTable; }
|
||||
|
||||
SkBitmap fTable; // A 256x4 A8 image
|
||||
};
|
||||
|
||||
#endif // SkColorTable_DEFINED
|
||||
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* Copyright 2022 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkColorType_DEFINED
|
||||
#define SkColorType_DEFINED
|
||||
|
||||
#include "include/core/SkTypes.h"
|
||||
|
||||
/** \enum SkColorType
|
||||
Describes how pixel bits encode color. A pixel may be an alpha mask, a grayscale, RGB, or ARGB.
|
||||
|
||||
kN32_SkColorType selects the native 32-bit ARGB format for the current configuration. This can
|
||||
lead to inconsistent results across platforms, so use with caution.
|
||||
|
||||
By default, Skia operates with the assumption of a little-Endian system. The names of each
|
||||
SkColorType implicitly define the channel ordering and size in memory. Due to historical reasons
|
||||
the names do not follow 100% identical convention, but are typically labeled from least
|
||||
significant to most significant. To help clarify when the actual data layout differs from the
|
||||
default convention, every SkColorType's comment includes a bit-labeled description of a pixel
|
||||
in that color type on a LE system.
|
||||
|
||||
Unless specified otherwise, a channel's value is treated as an unsigned integer with a range of
|
||||
of [0, 2^N-1] and this is mapped uniformly to a floating point value of [0.0, 1.0]. Some color
|
||||
types instead store data directly in 32-bit floating point (assumed to be IEEE), or in 16-bit
|
||||
"half" floating point values. A half float, or F16/float16, is interpreted as FP 1-5-10 or
|
||||
Bits: [sign:15 exp:14..10 man:9..0]
|
||||
*/
|
||||
enum SkColorType : int {
|
||||
// Unknown or unrepresentable as an SkColorType.
|
||||
kUnknown_SkColorType,
|
||||
// Single channel data (8-bit) interpreted as an alpha value. RGB are 0.
|
||||
// Bits: [A:7..0]
|
||||
kAlpha_8_SkColorType,
|
||||
// Three channel BGR data (5 bits red, 6 bits green, 5 bits blue) packed into a LE 16-bit word.
|
||||
// NOTE: The name of this enum value does not match the standard convention for SkColorType.
|
||||
// Bits: [R:15..11 G:10..5 B:4..0]
|
||||
kRGB_565_SkColorType,
|
||||
// Four channel ABGR data (4 bits per channel) packed into a LE 16-bit word.
|
||||
// NOTE: The name of this enum value does not match the standard convention for SkColorType.
|
||||
// Bits: [R:15..12 G:11..8 B:7..4 A:3..0]
|
||||
kARGB_4444_SkColorType,
|
||||
// Four channel RGBA data (8 bits per channel) packed into a LE 32-bit word.
|
||||
// Bits: [A:31..24 B:23..16 G:15..8 R:7..0]
|
||||
kRGBA_8888_SkColorType,
|
||||
// Three channel RGB data (8 bits per channel) packed into a LE 32-bit word. The remaining bits
|
||||
// are ignored and alpha is forced to opaque.
|
||||
// Bits: [x:31..24 B:23..16 G:15..8 R:7..0]
|
||||
kRGB_888x_SkColorType,
|
||||
// Four channel BGRA data (8 bits per channel) packed into a LE 32-bit word. R and B are swapped
|
||||
// relative to kRGBA_8888.
|
||||
// Bits: [A:31..24 R:23..16 G:15..8 B:7..0]
|
||||
kBGRA_8888_SkColorType,
|
||||
// Four channel RGBA data (10 bits per color, 2 bits for alpha) packed into a LE 32-bit word.
|
||||
// Bits: [A:31..30 B:29..20 G:19..10 R:9..0]
|
||||
kRGBA_1010102_SkColorType,
|
||||
// Four channel BGRA data (10 bits per color, 2 bits for alpha) packed into a LE 32-bit word.
|
||||
// R and B are swapped relative to kRGBA_1010102.
|
||||
// Bits: [A:31..30 R:29..20 G:19..10 B:9..0]
|
||||
kBGRA_1010102_SkColorType,
|
||||
// Three channel RGB data (10 bits per channel) packed into a LE 32-bit word. The remaining bits
|
||||
// are ignored and alpha is forced to opaque.
|
||||
// Bits: [x:31..30 B:29..20 G:19..10 R:9..0]
|
||||
kRGB_101010x_SkColorType,
|
||||
// Three channel BGR data (10 bits per channel) packed into a LE 32-bit word. The remaining bits
|
||||
// are ignored and alpha is forced to opaque. R and B are swapped relative to kRGB_101010x.
|
||||
// Bits: [x:31..30 R:29..20 G:19..10 B:9..0]
|
||||
kBGR_101010x_SkColorType,
|
||||
// Three channel BGR data (10 bits per channel) packed into a LE 32-bit word. The remaining bits
|
||||
// are ignored and alpha is forced to opaque. Instead of normalizing [0, 1023] to [0.0, 1.0] the
|
||||
// color channels map to an extended range of [-0.752941, 1.25098], compatible with
|
||||
// MTLPixelFormatBGR10_XR.
|
||||
// Bits: [x:31..30 R:29..20 G:19..10 B:9..0]
|
||||
kBGR_101010x_XR_SkColorType,
|
||||
// Four channel BGRA data (10 bits per channel) packed into a LE 64-bit word. Each channel is
|
||||
// preceded by 6 bits of padding. Instead of normalizing [0, 1023] to [0.0, 1.0] the color and
|
||||
// alpha channels map to an extended range of [-0.752941, 1.25098], compatible with
|
||||
// MTLPixelFormatBGRA10_XR.
|
||||
// Bits: [A:63..54 x:53..48 R:47..38 x:37..32 G:31..22 x:21..16 B:15..6 x:5..0]
|
||||
kBGRA_10101010_XR_SkColorType,
|
||||
// Four channel RGBA data (10 bits per channel) packed into a LE 64-bit word. Each channel is
|
||||
// preceded by 6 bits of padding.
|
||||
// Bits: [A:63..54 x:53..48 B:47..38 x:37..32 G:31..22 x:21..16 R:15..6 x:5..0]
|
||||
kRGBA_10x6_SkColorType,
|
||||
// Single channel data (8-bit) interpreted as a grayscale value (e.g. replicated to RGB).
|
||||
// Bits: [G:7..0]
|
||||
kGray_8_SkColorType,
|
||||
// Four channel RGBA data (16-bit half-float per channel) packed into a LE 64-bit word. Values
|
||||
// are assumed to be in [0.0,1.0] range, unlike kRGBA_F16.
|
||||
// Bits: [A:63..48 B:47..32 G:31..16 R:15..0]
|
||||
kRGBA_F16Norm_SkColorType,
|
||||
// Four channel RGBA data (16-bit half-float per channel) packed into a LE 64-bit word.
|
||||
// This has extended range compared to kRGBA_F16Norm.
|
||||
// Bits: [A:63..48 B:47..32 G:31..16 R:15..0]
|
||||
kRGBA_F16_SkColorType,
|
||||
// Three channel RGB data (16-bit half-float per channel) packed into a LE 64-bit word. The last
|
||||
// 16 bits are ignored and alpha is forced to opaque.
|
||||
// Bits: [x:63..48 B:47..32 G:31..16 R:15..0]
|
||||
kRGB_F16F16F16x_SkColorType,
|
||||
// Four channel RGBA data (32-bit float per channel) packed into a LE 128-bit word.
|
||||
// Bits: [A:127..96 B:95..64 G:63..32 R:31..0]
|
||||
kRGBA_F32_SkColorType,
|
||||
// Two channel RG data (8 bits per channel). Blue is forced to 0, alpha is forced to opaque.
|
||||
// Bits: [G:15..8 R:7..0]
|
||||
kR8G8_unorm_SkColorType,
|
||||
// Single channel data (16-bit half-float) interpreted as alpha. RGB are 0.
|
||||
// Bits: [A:15..0]
|
||||
kA16_float_SkColorType,
|
||||
|
||||
// Single channel data (16 bits half-float) interpreted as red. G and B are forced to 0, alpha
|
||||
// is forced to opaque.
|
||||
// Bits: [R:15..0]
|
||||
kR16_float_SkColorType,
|
||||
// Two channel RG data (16-bit half-float per channel) packed into a LE 32-bit word.
|
||||
// Blue is forced to 0, alpha is forced to opaque.
|
||||
// Bits: [G:31..16 R:15..0]
|
||||
kR16G16_float_SkColorType,
|
||||
// Single channel data (16 bits) interpreted as alpha. RGB are 0.
|
||||
// Bits: [A:15..0]
|
||||
kA16_unorm_SkColorType,
|
||||
// Single channel data (16 bits) interpreted as red. G and B are forced to 0, alpha is forced to
|
||||
// opaque.
|
||||
// Bits: [R:15..0]
|
||||
kR16_unorm_SkColorType,
|
||||
// Two channel RG data (16 bits per channel) packed into a LE 32-bit word. B is forced to 0,
|
||||
// alpha is forced to opaque.
|
||||
// Bits: [G:31..16 R:15..0]
|
||||
kR16G16_unorm_SkColorType,
|
||||
// Four channel RGBA data (16 bits per channel) packed into a LE 64-bit word.
|
||||
// Bits: [A:63..48 B:47..32 G:31..16 R:15..0]
|
||||
kR16G16B16A16_unorm_SkColorType,
|
||||
// Four channel RGBA data (8 bits per channel) packed into a LE 32-bit word. The RGB values are
|
||||
// assumed to be encoded with the sRGB transfer function, which can be decoded automatically
|
||||
// by GPU hardware with certain texture formats.
|
||||
// Bits: [A:31..24 B:23..16 G:15..8 R:7..0]
|
||||
kSRGBA_8888_SkColorType,
|
||||
// Single channel data (8 bits) interpreted as red. G and B are forced to 0, alpha is forced to
|
||||
// opaque.
|
||||
// Bits: [R:7..0]
|
||||
kR8_unorm_SkColorType,
|
||||
|
||||
kLastEnum_SkColorType = kR8_unorm_SkColorType, //!< last valid value
|
||||
|
||||
#if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
|
||||
kN32_SkColorType = kBGRA_8888_SkColorType,//!< native 32-bit BGRA encoding
|
||||
|
||||
#elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
|
||||
kN32_SkColorType = kRGBA_8888_SkColorType,//!< native 32-bit RGBA encoding
|
||||
|
||||
#else
|
||||
#error "SK_*32_SHIFT values must correspond to BGRA or RGBA byte order"
|
||||
#endif
|
||||
};
|
||||
static constexpr int kSkColorTypeCnt = static_cast<int>(kLastEnum_SkColorType) + 1;
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,215 @@
|
|||
/*
|
||||
* Copyright 2018 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkContourMeasure_DEFINED
|
||||
#define SkContourMeasure_DEFINED
|
||||
|
||||
#include "include/core/SkPathTypes.h" // IWYU pragma: keep
|
||||
#include "include/core/SkPoint.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/core/SkScalar.h"
|
||||
#include "include/core/SkSpan.h"
|
||||
#include "include/core/SkTypes.h"
|
||||
#include "include/private/base/SkTDArray.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
|
||||
class SkMatrix;
|
||||
class SkPath;
|
||||
class SkPathBuilder;
|
||||
|
||||
class SK_API SkContourMeasure : public SkRefCnt {
|
||||
public:
|
||||
/** Return the length of the contour.
|
||||
*/
|
||||
SkScalar length() const { return fLength; }
|
||||
|
||||
/** Pins distance to 0 <= distance <= length(), and then computes the corresponding
|
||||
* position and tangent.
|
||||
*/
|
||||
[[nodiscard]] bool getPosTan(SkScalar distance, SkPoint* position, SkVector* tangent) const;
|
||||
|
||||
enum MatrixFlags {
|
||||
kGetPosition_MatrixFlag = 0x01,
|
||||
kGetTangent_MatrixFlag = 0x02,
|
||||
kGetPosAndTan_MatrixFlag = kGetPosition_MatrixFlag | kGetTangent_MatrixFlag
|
||||
};
|
||||
|
||||
/** Pins distance to 0 <= distance <= getLength(), and then computes
|
||||
the corresponding matrix (by calling getPosTan).
|
||||
Returns false if there is no path, or a zero-length path was specified, in which case
|
||||
matrix is unchanged.
|
||||
*/
|
||||
[[nodiscard]] bool getMatrix(SkScalar distance, SkMatrix* matrix,
|
||||
MatrixFlags flags = kGetPosAndTan_MatrixFlag) const;
|
||||
|
||||
/** Given a start and stop distance, append to dst the intervening segment(s).
|
||||
If the segment is zero-length, return false, else return true.
|
||||
startD and stopD are pinned to legal values (0..getLength()). If startD > stopD
|
||||
then return false (and leave dst untouched).
|
||||
Begin the segment with a moveTo if startWithMoveTo is true
|
||||
*/
|
||||
[[nodiscard]] bool getSegment(SkScalar startD, SkScalar stopD, SkPathBuilder* dst,
|
||||
bool startWithMoveTo) const;
|
||||
|
||||
/** Return true if the contour is closed()
|
||||
*/
|
||||
bool isClosed() const { return fIsClosed; }
|
||||
|
||||
/** Measurement data for individual verbs.
|
||||
*/
|
||||
struct VerbMeasure {
|
||||
SkScalar fDistance; // Cumulative distance along the current contour.
|
||||
SkPathVerb fVerb; // Verb type.
|
||||
SkSpan<const SkPoint> fPts; // Verb points.
|
||||
};
|
||||
|
||||
private:
|
||||
struct Segment;
|
||||
|
||||
public:
|
||||
/** Utility for iterating over the current contour verbs:
|
||||
*
|
||||
* for (const auto verb_measure : contour_measure) {
|
||||
* ...
|
||||
* }
|
||||
*/
|
||||
class ForwardVerbIterator final {
|
||||
public:
|
||||
VerbMeasure operator*() const;
|
||||
|
||||
ForwardVerbIterator& operator++() {
|
||||
SkASSERT(!fSegments.empty());
|
||||
|
||||
fSegments = LastSegForCurrentVerb(fSegments.subspan(1));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const ForwardVerbIterator& other) const {
|
||||
SkASSERT(fSegments.data() != other.fSegments.data() ||
|
||||
fSegments.size() == other.fSegments.size());
|
||||
return fSegments.data() == other.fSegments.data();
|
||||
}
|
||||
|
||||
bool operator!=(const ForwardVerbIterator& other) const {
|
||||
return !((*this) == other);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class SkContourMeasure;
|
||||
|
||||
ForwardVerbIterator(SkSpan<const Segment> segs, SkSpan<const SkPoint> pts)
|
||||
: fSegments(LastSegForCurrentVerb(segs))
|
||||
, fPts(pts) {}
|
||||
|
||||
static SkSpan<const Segment> LastSegForCurrentVerb(const SkSpan<const Segment>& segs) {
|
||||
size_t i = 1;
|
||||
while (i < segs.size() && segs[0].fPtIndex == segs[i].fPtIndex) {
|
||||
++i;
|
||||
}
|
||||
|
||||
return segs.subspan(i - 1);
|
||||
}
|
||||
|
||||
// Remaining segments for forward iteration. The first segment in the span is
|
||||
// adjusted to always point to the last segment of the current verb, such that its distance
|
||||
// corresponds to the verb distance.
|
||||
SkSpan<const Segment> fSegments;
|
||||
|
||||
// All path points (indexed in segments).
|
||||
SkSpan<const SkPoint> fPts;
|
||||
};
|
||||
|
||||
ForwardVerbIterator begin() const {
|
||||
return ForwardVerbIterator(fSegments, fPts);
|
||||
}
|
||||
ForwardVerbIterator end() const {
|
||||
return ForwardVerbIterator(SkSpan(fSegments.end(), 0), fPts);
|
||||
}
|
||||
|
||||
private:
|
||||
struct Segment {
|
||||
SkScalar fDistance; // total distance up to this point
|
||||
unsigned fPtIndex; // index into the fPts array
|
||||
unsigned fTValue : 30;
|
||||
unsigned fType : 2; // actually the enum SkSegType
|
||||
// See SkPathMeasurePriv.h
|
||||
|
||||
SkScalar getScalarT() const;
|
||||
|
||||
static const Segment* Next(const Segment* seg) {
|
||||
unsigned ptIndex = seg->fPtIndex;
|
||||
do {
|
||||
++seg;
|
||||
} while (seg->fPtIndex == ptIndex);
|
||||
return seg;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
const SkTDArray<Segment> fSegments;
|
||||
const SkTDArray<SkPoint> fPts; // Points used to define the segments
|
||||
|
||||
const SkScalar fLength;
|
||||
const bool fIsClosed;
|
||||
|
||||
SkContourMeasure(SkTDArray<Segment>&& segs, SkTDArray<SkPoint>&& pts,
|
||||
SkScalar length, bool isClosed);
|
||||
~SkContourMeasure() override {}
|
||||
|
||||
const Segment* distanceToSegment(SkScalar distance, SkScalar* t) const;
|
||||
|
||||
friend class SkContourMeasureIter;
|
||||
friend class SkPathMeasurePriv;
|
||||
};
|
||||
|
||||
class SK_API SkContourMeasureIter {
|
||||
public:
|
||||
SkContourMeasureIter();
|
||||
/**
|
||||
* Initialize the Iter with a path.
|
||||
* The parts of the path that are needed are copied, so the client is free to modify/delete
|
||||
* the path after this call.
|
||||
*
|
||||
* resScale controls the precision of the measure. values > 1 increase the
|
||||
* precision (and possibly slow down the computation).
|
||||
*/
|
||||
SkContourMeasureIter(const SkPath& path, bool forceClosed, SkScalar resScale = 1);
|
||||
~SkContourMeasureIter();
|
||||
|
||||
SkContourMeasureIter(SkContourMeasureIter&&);
|
||||
SkContourMeasureIter& operator=(SkContourMeasureIter&&);
|
||||
|
||||
/**
|
||||
* Reset the Iter with a path.
|
||||
* The parts of the path that are needed are copied, so the client is free to modify/delete
|
||||
* the path after this call.
|
||||
*/
|
||||
void reset(const SkPath& path, bool forceClosed, SkScalar resScale = 1);
|
||||
|
||||
/**
|
||||
* Iterates through contours in path, returning a contour-measure object for each contour
|
||||
* in the path. Returns null when it is done.
|
||||
*
|
||||
* This only returns non-zero length contours, where a contour is the segments between
|
||||
* a kMove_Verb and either ...
|
||||
* - the next kMove_Verb
|
||||
* - kClose_Verb (1 or more)
|
||||
* - kDone_Verb
|
||||
* If it encounters a zero-length contour, it is skipped.
|
||||
*/
|
||||
sk_sp<SkContourMeasure> next();
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
|
||||
std::unique_ptr<Impl> fImpl;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright 2018 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkCoverageMode_DEFINED
|
||||
#define SkCoverageMode_DEFINED
|
||||
|
||||
/**
|
||||
* Describes geometric operations (ala SkRegion::Op) that can be applied to coverage bytes.
|
||||
* These can be thought of as variants of porter-duff (SkBlendMode) modes, but only applied
|
||||
* to the alpha channel.
|
||||
*
|
||||
* See SkMaskFilter for ways to use these when combining two different masks.
|
||||
*/
|
||||
enum class SkCoverageMode {
|
||||
kUnion, // A ∪ B A+B-A*B
|
||||
kIntersect, // A ∩ B A*B
|
||||
kDifference, // A - B A*(1-B)
|
||||
kReverseDifference, // B - A B*(1-A)
|
||||
kXor, // A ⊕ B A+B-2*A*B
|
||||
|
||||
kLast = kXor,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright 2018 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkCubicMap_DEFINED
|
||||
#define SkCubicMap_DEFINED
|
||||
|
||||
#include "include/core/SkPoint.h"
|
||||
#include "include/core/SkScalar.h"
|
||||
#include "include/core/SkTypes.h"
|
||||
|
||||
/**
|
||||
* Fast evaluation of a cubic ease-in / ease-out curve. This is defined as a parametric cubic
|
||||
* curve inside the unit square.
|
||||
*
|
||||
* pt[0] is implicitly { 0, 0 }
|
||||
* pt[3] is implicitly { 1, 1 }
|
||||
* pts[1,2].X are inside the unit [0..1]
|
||||
*/
|
||||
class SK_API SkCubicMap {
|
||||
public:
|
||||
SkCubicMap(SkPoint p1, SkPoint p2);
|
||||
|
||||
static bool IsLinear(SkPoint p1, SkPoint p2) {
|
||||
return SkScalarNearlyEqual(p1.fX, p1.fY) && SkScalarNearlyEqual(p2.fX, p2.fY);
|
||||
}
|
||||
|
||||
float computeYFromX(float x) const;
|
||||
|
||||
SkPoint computeFromT(float t) const;
|
||||
|
||||
private:
|
||||
enum Type {
|
||||
kLine_Type, // x == y
|
||||
kCubeRoot_Type, // At^3 == x
|
||||
kSolver_Type, // general monotonic cubic solver
|
||||
};
|
||||
|
||||
SkPoint fCoeff[3];
|
||||
Type fType;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,225 @@
|
|||
/*
|
||||
* 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 SkData_DEFINED
|
||||
#define SkData_DEFINED
|
||||
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/core/SkSpan.h"
|
||||
#include "include/private/base/SkAPI.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
|
||||
class SkStream;
|
||||
|
||||
/**
|
||||
* SkData holds a data buffer. It can be created to allocate its own buffer
|
||||
* for the contents, or to share a pointer to the client's buffer. The size and
|
||||
* address of the contents never change for the lifetime of the data object.
|
||||
*/
|
||||
class SK_API SkData final : public SkNVRefCnt<SkData> {
|
||||
public:
|
||||
/**
|
||||
* Returns true if this and rhs are the same size, and contain the same contents.
|
||||
* All empty objects compare as equal.
|
||||
*/
|
||||
bool operator==(const SkData& rhs) const;
|
||||
bool operator!=(const SkData& rhs) const { return !(*this == rhs); }
|
||||
|
||||
/**
|
||||
* Calls == operator, but first checks if other is null (in which case it returns false)
|
||||
*/
|
||||
bool equals(const SkData* other) const {
|
||||
return (other != nullptr) && *this == *other;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if both arguments are the same size and contain the same bytes, or if both
|
||||
* arguments are null.
|
||||
*/
|
||||
static bool Equals(const SkData* a, const SkData* b) {
|
||||
return (a == nullptr) ? (b == nullptr) : a->equals(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bytes stored.
|
||||
*/
|
||||
size_t size() const { return fSpan.size(); }
|
||||
|
||||
/**
|
||||
* Returns the ptr to the data.
|
||||
*/
|
||||
const void* data() const { return fSpan.data(); }
|
||||
|
||||
bool empty() const { return fSpan.empty(); }
|
||||
|
||||
const uint8_t* bytes() const { return reinterpret_cast<const uint8_t*>(this->data()); }
|
||||
|
||||
SkSpan<const uint8_t> byteSpan() const { return {this->bytes(), this->size()}; }
|
||||
|
||||
/**
|
||||
* USE WITH CAUTION.
|
||||
* Be sure other 'owners' of this object are not accessing it in aother thread.
|
||||
*/
|
||||
void* writable_data() {
|
||||
return fSpan.data();
|
||||
}
|
||||
|
||||
/** Attempt to create a deep copy of the original data, using the default allocator.
|
||||
*
|
||||
* If offset+length > this->size(), then this returns nullptr.
|
||||
*/
|
||||
sk_sp<SkData> copySubset(size_t offset, size_t length) const;
|
||||
|
||||
/** Attempt to return a data that is a reference to a subset of the original data,
|
||||
* This will never make a deep copy of the contents, but will retain a reference
|
||||
* to the original data object.
|
||||
*
|
||||
* If offset+length > this->size(), then this returns nullptr.
|
||||
*/
|
||||
sk_sp<SkData> shareSubset(size_t offset, size_t length);
|
||||
sk_sp<const SkData> shareSubset(size_t offset, size_t length) const;
|
||||
|
||||
/**
|
||||
* Helper to copy a range of the data into a caller-provided buffer.
|
||||
* Returns the actual number of bytes copied, after clamping offset and
|
||||
* length to the size of this data. If buffer is NULL, it is ignored, and
|
||||
* only the computed number of bytes is returned.
|
||||
*/
|
||||
size_t copyRange(size_t offset, size_t length, void* buffer) const;
|
||||
|
||||
/**
|
||||
* Function that, if provided, will be called when the SkData goes out
|
||||
* of scope, allowing for custom allocation/freeing of the data's contents.
|
||||
*/
|
||||
typedef void (*ReleaseProc)(const void* ptr, void* context);
|
||||
|
||||
/**
|
||||
* Create a new dataref by copying the specified data
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
static sk_sp<SkData> MakeUninitialized(size_t length);
|
||||
|
||||
/**
|
||||
* Create a new data with zero-initialized contents. The caller should call writable_data()
|
||||
* to write into the buffer, but this must be done before another ref() is made.
|
||||
*/
|
||||
static sk_sp<SkData> MakeZeroInitialized(size_t length);
|
||||
|
||||
/**
|
||||
* Create a new dataref by copying the specified c-string
|
||||
* (a null-terminated array of bytes). The returned SkData will have size()
|
||||
* equal to strlen(cstr) + 1. If cstr is NULL, it will be treated the same
|
||||
* as "".
|
||||
*/
|
||||
static sk_sp<SkData> MakeWithCString(const char cstr[]);
|
||||
|
||||
/**
|
||||
* Create a new dataref, taking the ptr as is, and using the
|
||||
* releaseproc to free it. The proc may be NULL.
|
||||
*/
|
||||
static sk_sp<SkData> MakeWithProc(const void* ptr, size_t length, ReleaseProc proc, void* ctx);
|
||||
|
||||
/**
|
||||
* Call this when the data parameter is already const and will outlive the lifetime of the
|
||||
* SkData. Suitable for globals.
|
||||
*/
|
||||
static sk_sp<SkData> MakeWithoutCopy(const void* data, size_t length) {
|
||||
return MakeWithProc(data, length, NoopReleaseProc, nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new dataref from a pointer allocated by malloc. The Data object
|
||||
* takes ownership of that allocation, and will handling calling sk_free.
|
||||
*/
|
||||
static sk_sp<SkData> MakeFromMalloc(const void* data, size_t length);
|
||||
|
||||
/**
|
||||
* Create a new dataref the file with the specified path.
|
||||
* If the file cannot be opened, this returns NULL.
|
||||
*/
|
||||
static sk_sp<SkData> MakeFromFileName(const char path[]);
|
||||
|
||||
/**
|
||||
* Create a new dataref from a stdio FILE.
|
||||
* This does not take ownership of the FILE, nor close it.
|
||||
* The caller is free to close the FILE at its convenience.
|
||||
* The FILE must be open for reading only.
|
||||
* Returns NULL on failure.
|
||||
*/
|
||||
static sk_sp<SkData> MakeFromFILE(FILE* f);
|
||||
|
||||
/**
|
||||
* Create a new dataref from a file descriptor.
|
||||
* This does not take ownership of the file descriptor, nor close it.
|
||||
* The caller is free to close the file descriptor at its convenience.
|
||||
* The file descriptor must be open for reading only.
|
||||
* Returns NULL on failure.
|
||||
*/
|
||||
static sk_sp<SkData> MakeFromFD(int fd);
|
||||
|
||||
/**
|
||||
* Attempt to read size bytes into a SkData. If the read succeeds, return the data,
|
||||
* else return NULL. Either way the stream's cursor may have been changed as a result
|
||||
* of calling read().
|
||||
*/
|
||||
static sk_sp<SkData> MakeFromStream(SkStream*, size_t size);
|
||||
|
||||
/**
|
||||
* DEPRECATED variant of src->shareSubset(offset, length)
|
||||
*
|
||||
* This variant checks if shaerSubset() returned null (because offset or length were out-of-range)
|
||||
* and returns an empty SkData, rather than returning null.
|
||||
*/
|
||||
static sk_sp<SkData> MakeSubset(const SkData* src, size_t offset, size_t length) {
|
||||
if (sk_sp<SkData> dst = const_cast<SkData*>(src)->shareSubset(offset, length)) {
|
||||
return dst;
|
||||
}
|
||||
return SkData::MakeEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new empty dataref (or a reference to a shared empty dataref).
|
||||
* New or shared, the caller must see that unref() is eventually called.
|
||||
*/
|
||||
static sk_sp<SkData> MakeEmpty();
|
||||
|
||||
/**
|
||||
* DEPRECATED -- use empty()
|
||||
*/
|
||||
bool isEmpty() const { return fSpan.empty(); }
|
||||
|
||||
private:
|
||||
friend class SkNVRefCnt<SkData>;
|
||||
ReleaseProc fReleaseProc;
|
||||
void* fReleaseProcContext;
|
||||
SkSpan<std::byte> fSpan;
|
||||
|
||||
SkData(SkSpan<std::byte>, ReleaseProc, void* context);
|
||||
explicit SkData(size_t size); // inplace new/delete
|
||||
~SkData();
|
||||
|
||||
// Ensure the unsized delete is called.
|
||||
void operator delete(void* p);
|
||||
|
||||
// shared internal factory
|
||||
static sk_sp<SkData> PrivateNewWithCopy(const void* srcOrNull, size_t length);
|
||||
|
||||
static void NoopReleaseProc(const void*, void*); // {}
|
||||
|
||||
using INHERITED = SkRefCnt;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* Copyright 2013 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkDataTable_DEFINED
|
||||
#define SkDataTable_DEFINED
|
||||
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/private/base/SkAPI.h"
|
||||
#include "include/private/base/SkAssert.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
/**
|
||||
* Like SkData, SkDataTable holds an immutable data buffer. The data buffer is
|
||||
* organized into a table of entries, each with a length, so the entries are
|
||||
* not required to all be the same size.
|
||||
*/
|
||||
class SK_API SkDataTable : public SkRefCnt {
|
||||
public:
|
||||
/**
|
||||
* Returns true if the table is empty (i.e. has no entries).
|
||||
*/
|
||||
bool isEmpty() const { return 0 == fCount; }
|
||||
|
||||
/**
|
||||
* Return the number of entries in the table. 0 for an empty table
|
||||
*/
|
||||
int count() const { return fCount; }
|
||||
|
||||
/**
|
||||
* Return the size of the index'th entry in the table. The caller must
|
||||
* ensure that index is valid for this table.
|
||||
*/
|
||||
size_t atSize(int index) const;
|
||||
|
||||
/**
|
||||
* Return a pointer to the data of the index'th entry in the table.
|
||||
* The caller must ensure that index is valid for this table.
|
||||
*
|
||||
* @param size If non-null, this returns the byte size of this entry. This
|
||||
* will be the same value that atSize(index) would return.
|
||||
*/
|
||||
const void* at(int index, size_t* size = nullptr) const;
|
||||
|
||||
template <typename T>
|
||||
const T* atT(int index, size_t* size = nullptr) const {
|
||||
return reinterpret_cast<const T*>(this->at(index, size));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index'th entry as a c-string, and assumes that the trailing
|
||||
* null byte had been copied into the table as well.
|
||||
*/
|
||||
const char* atStr(int index) const {
|
||||
size_t size;
|
||||
const char* str = this->atT<const char>(index, &size);
|
||||
SkASSERT(strlen(str) + 1 == size);
|
||||
return str;
|
||||
}
|
||||
|
||||
typedef void (*FreeProc)(void* context);
|
||||
|
||||
static sk_sp<SkDataTable> MakeEmpty();
|
||||
|
||||
/**
|
||||
* Return a new DataTable that contains a copy of the data stored in each
|
||||
* "array".
|
||||
*
|
||||
* @param ptrs array of points to each element to be copied into the table.
|
||||
* @param sizes array of byte-lengths for each entry in the corresponding
|
||||
* ptrs[] array.
|
||||
* @param count the number of array elements in ptrs[] and sizes[] to copy.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @param array contiguous array of data for all elements to be copied.
|
||||
* @param elemSize byte-length for a given element.
|
||||
* @param count the number of entries to be copied out of array. The number
|
||||
* of bytes that will be copied is count * elemSize.
|
||||
*/
|
||||
static sk_sp<SkDataTable> MakeCopyArray(const void* array, size_t elemSize, int count);
|
||||
|
||||
static sk_sp<SkDataTable> MakeArrayProc(const void* array, size_t elemSize, int count,
|
||||
FreeProc proc, void* context);
|
||||
|
||||
private:
|
||||
struct Dir {
|
||||
const void* fPtr;
|
||||
uintptr_t fSize;
|
||||
};
|
||||
|
||||
int fCount;
|
||||
size_t fElemSize;
|
||||
union {
|
||||
const Dir* fDir;
|
||||
const char* fElems;
|
||||
} fU;
|
||||
|
||||
FreeProc fFreeProc;
|
||||
void* fFreeProcContext;
|
||||
|
||||
SkDataTable();
|
||||
SkDataTable(const void* array, size_t elemSize, int count,
|
||||
FreeProc, void* context);
|
||||
SkDataTable(const Dir*, int count, FreeProc, void* context);
|
||||
~SkDataTable() override;
|
||||
|
||||
friend class SkDataTableBuilder; // access to Dir
|
||||
|
||||
using INHERITED = SkRefCnt;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright 2013 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkDocument_DEFINED
|
||||
#define SkDocument_DEFINED
|
||||
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/core/SkScalar.h"
|
||||
#include "include/private/base/SkAPI.h"
|
||||
|
||||
class SkCanvas;
|
||||
class SkWStream;
|
||||
struct SkRect;
|
||||
|
||||
/** SK_ScalarDefaultDPI is 72 dots per inch. */
|
||||
static constexpr SkScalar SK_ScalarDefaultRasterDPI = 72.0f;
|
||||
|
||||
/**
|
||||
* High-level API for creating a document-based canvas. To use..
|
||||
*
|
||||
* 1. Create a document, specifying a stream to store the output.
|
||||
* 2. For each "page" of content:
|
||||
* a. canvas = doc->beginPage(...)
|
||||
* b. draw_my_content(canvas);
|
||||
* c. doc->endPage();
|
||||
* 3. Close the document with doc->close().
|
||||
*/
|
||||
class SK_API SkDocument : public SkRefCnt {
|
||||
public:
|
||||
|
||||
/**
|
||||
* 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
|
||||
* scope when endPage() or close() is called, or the document is deleted.
|
||||
* This will call endPage() if there is a currently active page.
|
||||
*/
|
||||
SkCanvas* beginPage(SkScalar width, SkScalar height, const SkRect* content = nullptr);
|
||||
|
||||
/**
|
||||
* Call endPage() when the content for the current page has been drawn
|
||||
* (into the canvas returned by beginPage()). After this call the canvas
|
||||
* returned by beginPage() will be out-of-scope.
|
||||
*/
|
||||
void endPage();
|
||||
|
||||
/**
|
||||
* Call close() when all pages have been drawn. This will close the file
|
||||
* 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.
|
||||
*/
|
||||
void close();
|
||||
|
||||
/**
|
||||
* Call abort() to stop producing the document immediately.
|
||||
* The stream output must be ignored, and should not be trusted.
|
||||
*/
|
||||
void abort();
|
||||
|
||||
protected:
|
||||
explicit SkDocument(SkWStream*);
|
||||
|
||||
// note: subclasses must call close() in their destructor, as the base class
|
||||
// cannot do this for them.
|
||||
~SkDocument() override;
|
||||
|
||||
virtual SkCanvas* onBeginPage(SkScalar width, SkScalar height) = 0;
|
||||
virtual void onEndPage() = 0;
|
||||
virtual void onClose(SkWStream*) = 0;
|
||||
virtual void onAbort() = 0;
|
||||
|
||||
// Allows subclasses to write to the stream as pages are written.
|
||||
SkWStream* getStream() { return fStream; }
|
||||
|
||||
enum State {
|
||||
kBetweenPages_State,
|
||||
kInPage_State,
|
||||
kClosed_State
|
||||
};
|
||||
State getState() const { return fState; }
|
||||
|
||||
private:
|
||||
SkWStream* fStream;
|
||||
State fState;
|
||||
|
||||
using INHERITED = SkRefCnt;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
* Copyright 2014 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkDrawable_DEFINED
|
||||
#define SkDrawable_DEFINED
|
||||
|
||||
#include "include/core/SkFlattenable.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/core/SkScalar.h"
|
||||
#include "include/private/base/SkAPI.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
class GrBackendDrawableInfo;
|
||||
class SkCanvas;
|
||||
class SkMatrix;
|
||||
class SkPicture;
|
||||
enum class GrBackendApi : unsigned int;
|
||||
struct SkDeserialProcs;
|
||||
struct SkIRect;
|
||||
struct SkImageInfo;
|
||||
struct SkRect;
|
||||
|
||||
/**
|
||||
* Base-class for objects that draw into SkCanvas.
|
||||
*
|
||||
* The object has a generation ID, which is guaranteed to be unique across all drawables. To
|
||||
* 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 SK_API SkDrawable : public SkFlattenable {
|
||||
public:
|
||||
/**
|
||||
* Draws into the specified content. The drawing sequence will be balanced upon return
|
||||
* (i.e. the saveLevel() on the canvas will match what it was when draw() was called,
|
||||
* and the current matrix and clip settings will not be changed.
|
||||
*/
|
||||
void draw(SkCanvas*, const SkMatrix* = nullptr);
|
||||
void draw(SkCanvas*, SkScalar x, SkScalar y);
|
||||
|
||||
/**
|
||||
* When using the GPU backend it is possible for a drawable to execute using the underlying 3D
|
||||
* API rather than the SkCanvas API. It does so by creating a GpuDrawHandler. The GPU backend
|
||||
* is deferred so the handler will be given access to the 3D API at the correct point in the
|
||||
* drawing stream as the GPU backend flushes. Since the drawable may mutate, each time it is
|
||||
* drawn to a GPU-backed canvas a new handler is snapped, representing the drawable's state at
|
||||
* the time of the snap.
|
||||
*
|
||||
* When the GPU backend flushes to the 3D API it will call the draw method on the
|
||||
* GpuDrawHandler. At this time the drawable may add commands to the stream of GPU commands for
|
||||
* the unerlying 3D API. The draw function takes a GrBackendDrawableInfo which contains
|
||||
* information about the current state of 3D API which the caller must respect. See
|
||||
* GrBackendDrawableInfo for more specific details on what information is sent and the
|
||||
* requirements for different 3D APIs.
|
||||
*
|
||||
* Additionaly there may be a slight delay from when the drawable adds its commands to when
|
||||
* those commands are actually submitted to the GPU. Thus the drawable or GpuDrawHandler is
|
||||
* required to keep any resources that are used by its added commands alive and valid until
|
||||
* those commands are submitted to the GPU. The GpuDrawHandler will be kept alive and then
|
||||
* deleted once the commands are submitted to the GPU. The dtor of the GpuDrawHandler is the
|
||||
* signal to the drawable that the commands have all been submitted. Different 3D APIs may have
|
||||
* additional requirements for certain resources which require waiting for the GPU to finish
|
||||
* all work on those resources before reusing or deleting them. In this case, the drawable can
|
||||
* use the dtor call of the GpuDrawHandler to add a fence to the GPU to track when the GPU work
|
||||
* has completed.
|
||||
*
|
||||
* Currently this is only supported for the GPU Vulkan backend.
|
||||
*/
|
||||
|
||||
class GpuDrawHandler {
|
||||
public:
|
||||
virtual ~GpuDrawHandler() {}
|
||||
|
||||
virtual void draw(const GrBackendDrawableInfo&) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Snaps off a GpuDrawHandler to represent the state of the SkDrawable at the time the snap is
|
||||
* called. This is used for executing GPU backend specific draws intermixed with normal Skia GPU
|
||||
* draws. The GPU API, which will be used for the draw, as well as the full matrix, device clip
|
||||
* bounds and imageInfo of the target buffer are passed in as inputs.
|
||||
*/
|
||||
std::unique_ptr<GpuDrawHandler> snapGpuDrawHandler(GrBackendApi backendApi,
|
||||
const SkMatrix& matrix,
|
||||
const SkIRect& clipBounds,
|
||||
const SkImageInfo& bufferInfo) {
|
||||
return this->onSnapGpuDrawHandler(backendApi, matrix, clipBounds, bufferInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an SkPicture with the contents of this SkDrawable.
|
||||
*/
|
||||
sk_sp<SkPicture> makePictureSnapshot();
|
||||
|
||||
/**
|
||||
* Return a unique value for this instance. If two calls to this return the same value,
|
||||
* it is presumed that calling the draw() method will render the same thing as well.
|
||||
*
|
||||
* Subclasses that change their state should call notifyDrawingChanged() to ensure that
|
||||
* a new value will be returned the next time it is called.
|
||||
*/
|
||||
uint32_t getGenerationID();
|
||||
|
||||
/**
|
||||
* Return the (conservative) bounds of what the drawable will draw. If the drawable can
|
||||
* change what it draws (e.g. animation or in response to some external change), then this
|
||||
* must return a bounds that is always valid for all possible states.
|
||||
*/
|
||||
SkRect getBounds();
|
||||
|
||||
/**
|
||||
* Return approximately how many bytes would be freed if this drawable is destroyed.
|
||||
* The base implementation returns 0 to indicate that this is unknown.
|
||||
*/
|
||||
size_t approximateBytesUsed();
|
||||
|
||||
/**
|
||||
* Calling this invalidates the previous generation ID, and causes a new one to be computed
|
||||
* the next time getGenerationID() is called. Typically this is called by the object itself,
|
||||
* in response to its internal state changing.
|
||||
*/
|
||||
void notifyDrawingChanged();
|
||||
|
||||
static SkFlattenable::Type GetFlattenableType() {
|
||||
return kSkDrawable_Type;
|
||||
}
|
||||
|
||||
SkFlattenable::Type getFlattenableType() const override {
|
||||
return kSkDrawable_Type;
|
||||
}
|
||||
|
||||
static sk_sp<SkDrawable> Deserialize(const void* data, size_t size,
|
||||
const SkDeserialProcs* procs = nullptr) {
|
||||
return sk_sp<SkDrawable>(static_cast<SkDrawable*>(
|
||||
SkFlattenable::Deserialize(
|
||||
kSkDrawable_Type, data, size, procs).release()));
|
||||
}
|
||||
|
||||
Factory getFactory() const override { return nullptr; }
|
||||
const char* getTypeName() const override { return nullptr; }
|
||||
|
||||
protected:
|
||||
SkDrawable();
|
||||
|
||||
virtual SkRect onGetBounds() = 0;
|
||||
virtual size_t onApproximateBytesUsed();
|
||||
virtual void onDraw(SkCanvas*) = 0;
|
||||
|
||||
virtual std::unique_ptr<GpuDrawHandler> onSnapGpuDrawHandler(GrBackendApi, const SkMatrix&,
|
||||
const SkIRect& /*clipBounds*/,
|
||||
const SkImageInfo&) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// TODO: Delete this once Android gets updated to take the clipBounds version above.
|
||||
virtual std::unique_ptr<GpuDrawHandler> onSnapGpuDrawHandler(GrBackendApi, const SkMatrix&) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default implementation calls onDraw() with a canvas that records into a picture. Subclasses
|
||||
* may override if they have a more efficient way to return a picture for the current state
|
||||
* of their drawable. Note: this picture must draw the same as what would be drawn from
|
||||
* onDraw().
|
||||
*/
|
||||
virtual sk_sp<SkPicture> onMakePictureSnapshot();
|
||||
|
||||
private:
|
||||
int32_t fGenerationID;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright 2017 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkExecutor_DEFINED
|
||||
#define SkExecutor_DEFINED
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include "include/core/SkTypes.h"
|
||||
|
||||
class SK_API SkExecutor {
|
||||
public:
|
||||
virtual ~SkExecutor();
|
||||
|
||||
// Create a thread pool SkExecutor with a fixed thread count, by default the number of cores.
|
||||
static std::unique_ptr<SkExecutor> MakeFIFOThreadPool(int threads = 0,
|
||||
bool allowBorrowing = true);
|
||||
static std::unique_ptr<SkExecutor> MakeLIFOThreadPool(int threads = 0,
|
||||
bool allowBorrowing = true);
|
||||
|
||||
// A work list is the queue or stack to which work is added and removed. The above two
|
||||
// factory functions create an executor with only one list while the following two factories
|
||||
// can create executors with multiple work lists. Having multiple work lists allows for
|
||||
// prioritization with work being pulled from the lower indexed work lists first - with
|
||||
// work list '0' being the highest priority.
|
||||
static std::unique_ptr<SkExecutor> MakeMultiListFIFOThreadPool(int numWorkLists,
|
||||
int threads = 0,
|
||||
bool allowBorrowing = true);
|
||||
static std::unique_ptr<SkExecutor> MakeMultiListLIFOThreadPool(int numWorkLists,
|
||||
int threads = 0,
|
||||
bool allowBorrowing = true);
|
||||
|
||||
// There is always a default SkExecutor available by calling SkExecutor::GetDefault().
|
||||
static SkExecutor& GetDefault();
|
||||
static void SetDefault(SkExecutor*); // Does not take ownership. Not thread safe.
|
||||
|
||||
// Add work to execute.
|
||||
virtual void add(std::function<void(void)> fn, int /* workList */) { this->add(std::move(fn)); }
|
||||
|
||||
// deprecated
|
||||
virtual void add(std::function<void(void)>) = 0;
|
||||
|
||||
// Returns the number of discarded work units
|
||||
virtual int discardAllPendingWork() { return 0; }
|
||||
|
||||
// If it makes sense for this executor, use this thread to execute work for a little while.
|
||||
virtual void borrow() {}
|
||||
|
||||
protected:
|
||||
SkExecutor() = default;
|
||||
SkExecutor(const SkExecutor&) = delete;
|
||||
SkExecutor& operator=(const SkExecutor&) = delete;
|
||||
};
|
||||
|
||||
#endif//SkExecutor_DEFINED
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* 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 SkFlattenable_DEFINED
|
||||
#define SkFlattenable_DEFINED
|
||||
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/core/SkTypes.h"
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
class SkData;
|
||||
class SkReadBuffer;
|
||||
class SkWriteBuffer;
|
||||
struct SkDeserialProcs;
|
||||
struct SkSerialProcs;
|
||||
|
||||
/** \class SkFlattenable
|
||||
|
||||
SkFlattenable is the base class for objects that need to be flattened
|
||||
into a data stream for either transport or as part of the key to the
|
||||
font cache.
|
||||
*/
|
||||
class SK_API SkFlattenable : public SkRefCnt {
|
||||
public:
|
||||
enum Type {
|
||||
kSkColorFilter_Type,
|
||||
kSkBlender_Type,
|
||||
kSkDrawable_Type,
|
||||
kSkDrawLooper_Type, // no longer supported by Skia
|
||||
kSkImageFilter_Type,
|
||||
kSkMaskFilter_Type,
|
||||
kSkPathEffect_Type,
|
||||
kSkShader_Type,
|
||||
};
|
||||
|
||||
typedef sk_sp<SkFlattenable> (*Factory)(SkReadBuffer&);
|
||||
|
||||
SkFlattenable() {}
|
||||
|
||||
/** Implement this to return a factory function pointer that can be called
|
||||
to recreate your class given a buffer (previously written to by your
|
||||
override of flatten().
|
||||
*/
|
||||
virtual Factory getFactory() const = 0;
|
||||
|
||||
/**
|
||||
* Returns the name of the object's class.
|
||||
*/
|
||||
virtual const char* getTypeName() const = 0;
|
||||
|
||||
static Factory NameToFactory(const char name[]);
|
||||
static const char* FactoryToName(Factory);
|
||||
|
||||
static void Register(const char name[], Factory);
|
||||
|
||||
/**
|
||||
* Override this if your subclass needs to record data that it will need to recreate itself
|
||||
* from its CreateProc (returned by getFactory()).
|
||||
*
|
||||
* DEPRECATED public : will move to protected ... use serialize() instead
|
||||
*/
|
||||
virtual void flatten(SkWriteBuffer&) const {}
|
||||
|
||||
virtual Type getFlattenableType() const = 0;
|
||||
|
||||
//
|
||||
// public ways to serialize / deserialize
|
||||
//
|
||||
sk_sp<SkData> serialize(const SkSerialProcs* = nullptr) const;
|
||||
size_t serialize(void* memory, size_t memory_size,
|
||||
const SkSerialProcs* = nullptr) const;
|
||||
static sk_sp<SkFlattenable> Deserialize(Type, const void* data, size_t length,
|
||||
const SkDeserialProcs* procs = nullptr);
|
||||
|
||||
protected:
|
||||
class PrivateInitializer {
|
||||
public:
|
||||
static void InitEffects();
|
||||
static void InitImageFilters();
|
||||
};
|
||||
|
||||
private:
|
||||
static void RegisterFlattenablesIfNeeded();
|
||||
static void Finalize();
|
||||
|
||||
friend class SkGraphics;
|
||||
|
||||
using INHERITED = SkRefCnt;
|
||||
};
|
||||
|
||||
#if defined(SK_DISABLE_EFFECT_DESERIALIZATION)
|
||||
#define SK_REGISTER_FLATTENABLE(type) do{}while(false)
|
||||
|
||||
#define SK_FLATTENABLE_HOOKS(type) \
|
||||
static sk_sp<SkFlattenable> CreateProc(SkReadBuffer&); \
|
||||
friend class SkFlattenable::PrivateInitializer; \
|
||||
Factory getFactory() const override { return nullptr; } \
|
||||
const char* getTypeName() const override { return #type; }
|
||||
#else
|
||||
#define SK_REGISTER_FLATTENABLE(type) \
|
||||
SkFlattenable::Register(#type, type::CreateProc)
|
||||
|
||||
#define SK_FLATTENABLE_HOOKS(type) \
|
||||
static sk_sp<SkFlattenable> CreateProc(SkReadBuffer&); \
|
||||
friend class SkFlattenable::PrivateInitializer; \
|
||||
Factory getFactory() const override { return type::CreateProc; } \
|
||||
const char* getTypeName() const override { return #type; }
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,536 @@
|
|||
/*
|
||||
* Copyright 2014 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkFont_DEFINED
|
||||
#define SkFont_DEFINED
|
||||
|
||||
#include "include/core/SkPath.h"
|
||||
#include "include/core/SkPoint.h" // IWYU pragma: keep (for unspanned apis)
|
||||
#include "include/core/SkRect.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/core/SkScalar.h"
|
||||
#include "include/core/SkSpan.h"
|
||||
#include "include/core/SkTypeface.h"
|
||||
#include "include/core/SkTypes.h"
|
||||
#include "include/private/base/SkTo.h"
|
||||
#include "include/private/base/SkTypeTraits.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
class SkMatrix;
|
||||
class SkPaint;
|
||||
class SkStrikeRef;
|
||||
enum class SkFontHinting;
|
||||
enum class SkTextEncoding;
|
||||
struct SkFontMetrics;
|
||||
|
||||
namespace skcpu { class GlyphRunListPainter; }
|
||||
|
||||
/** \class SkFont
|
||||
SkFont controls options applied when drawing and measuring text.
|
||||
*/
|
||||
class SK_API SkFont {
|
||||
public:
|
||||
/** Whether edge pixels draw opaque or with partial transparency.
|
||||
*/
|
||||
enum class Edging {
|
||||
kAlias, //!< no transparent pixels on glyph edges
|
||||
kAntiAlias, //!< may have transparent pixels on glyph edges
|
||||
kSubpixelAntiAlias, //!< glyph positioned in pixel using transparency
|
||||
};
|
||||
|
||||
/** Constructs SkFont with default values.
|
||||
|
||||
@return default initialized SkFont
|
||||
*/
|
||||
SkFont();
|
||||
|
||||
/** Constructs SkFont with default values with SkTypeface and size.
|
||||
|
||||
@param typeface font and style used to draw and measure text
|
||||
@param size EM size in local coordinate units
|
||||
@return initialized SkFont
|
||||
*/
|
||||
SkFont(sk_sp<SkTypeface> typeface, SkScalar size);
|
||||
|
||||
/** Constructs SkFont with default values with SkTypeface.
|
||||
|
||||
@param typeface font and style used to draw and measure text
|
||||
@return initialized SkFont
|
||||
*/
|
||||
explicit SkFont(sk_sp<SkTypeface> typeface);
|
||||
|
||||
|
||||
/** Constructs SkFont with default values with SkTypeface and size in points,
|
||||
horizontal scale, and horizontal skew. Horizontal scale emulates condensed
|
||||
and expanded fonts. Horizontal skew emulates oblique fonts.
|
||||
|
||||
@param typeface font and style used to draw and measure text
|
||||
@param size EM size in local coordinate units
|
||||
@param scaleX text horizontal scale
|
||||
@param skewX additional shear on x-axis relative to y-axis
|
||||
@return initialized SkFont
|
||||
*/
|
||||
SkFont(sk_sp<SkTypeface> typeface, SkScalar size, SkScalar scaleX, SkScalar skewX);
|
||||
|
||||
|
||||
/** Compares SkFont and font, and returns true if they are equivalent.
|
||||
May return false if SkTypeface has identical contents but different pointers.
|
||||
|
||||
@param font font to compare
|
||||
@return true if SkFont pair are equivalent
|
||||
*/
|
||||
bool operator==(const SkFont& font) const;
|
||||
|
||||
/** Compares SkFont and font, and returns true if they are not equivalent.
|
||||
May return true if SkTypeface has identical contents but different pointers.
|
||||
|
||||
@param font font to compare
|
||||
@return true if SkFont pair are not equivalent
|
||||
*/
|
||||
bool operator!=(const SkFont& font) const { return !(*this == font); }
|
||||
|
||||
/** If true, instructs the font manager to always hint glyphs.
|
||||
Returned value is only meaningful if platform uses FreeType as the font manager.
|
||||
|
||||
@return true if all glyphs are hinted
|
||||
*/
|
||||
bool isForceAutoHinting() const { return SkToBool(fFlags & kForceAutoHinting_PrivFlag); }
|
||||
|
||||
/** Returns true if font engine may return glyphs from font bitmaps instead of from outlines.
|
||||
|
||||
@return true if glyphs may be font bitmaps
|
||||
*/
|
||||
bool isEmbeddedBitmaps() const { return SkToBool(fFlags & kEmbeddedBitmaps_PrivFlag); }
|
||||
|
||||
/** Returns true if glyphs may be drawn at sub-pixel offsets.
|
||||
|
||||
@return true if glyphs may be drawn at sub-pixel offsets.
|
||||
*/
|
||||
bool isSubpixel() const { return SkToBool(fFlags & kSubpixel_PrivFlag); }
|
||||
|
||||
/** Returns true if font and glyph metrics are requested to be linearly scalable.
|
||||
|
||||
@return true if font and glyph metrics are requested to be linearly scalable.
|
||||
*/
|
||||
bool isLinearMetrics() const { return SkToBool(fFlags & kLinearMetrics_PrivFlag); }
|
||||
|
||||
/** Returns true if bold is approximated by increasing the stroke width when creating glyph
|
||||
bitmaps from outlines.
|
||||
|
||||
@return bold is approximated through stroke width
|
||||
*/
|
||||
bool isEmbolden() const { return SkToBool(fFlags & kEmbolden_PrivFlag); }
|
||||
|
||||
/** Returns true if baselines will be snapped to pixel positions when the current transformation
|
||||
matrix is axis aligned.
|
||||
|
||||
@return baselines may be snapped to pixels
|
||||
*/
|
||||
bool isBaselineSnap() const { return SkToBool(fFlags & kBaselineSnap_PrivFlag); }
|
||||
|
||||
/** Sets whether to always hint glyphs.
|
||||
If forceAutoHinting is set, instructs the font manager to always hint glyphs.
|
||||
|
||||
Only affects platforms that use FreeType as the font manager.
|
||||
|
||||
@param forceAutoHinting setting to always hint glyphs
|
||||
*/
|
||||
void setForceAutoHinting(bool forceAutoHinting);
|
||||
|
||||
/** Requests, but does not require, to use bitmaps in fonts instead of outlines.
|
||||
|
||||
@param embeddedBitmaps setting to use bitmaps in fonts
|
||||
*/
|
||||
void setEmbeddedBitmaps(bool embeddedBitmaps);
|
||||
|
||||
/** Requests, but does not require, that glyphs respect sub-pixel positioning.
|
||||
|
||||
@param subpixel setting for sub-pixel positioning
|
||||
*/
|
||||
void setSubpixel(bool subpixel);
|
||||
|
||||
/** Requests, but does not require, linearly scalable font and glyph metrics.
|
||||
|
||||
For outline fonts 'true' means font and glyph metrics should ignore hinting and rounding.
|
||||
Note that some bitmap formats may not be able to scale linearly and will ignore this flag.
|
||||
|
||||
@param linearMetrics setting for linearly scalable font and glyph metrics.
|
||||
*/
|
||||
void setLinearMetrics(bool linearMetrics);
|
||||
|
||||
/** Increases stroke width when creating glyph bitmaps to approximate a bold typeface.
|
||||
|
||||
@param embolden setting for bold approximation
|
||||
*/
|
||||
void setEmbolden(bool embolden);
|
||||
|
||||
/** Requests that baselines be snapped to pixels when the current transformation matrix is axis
|
||||
aligned.
|
||||
|
||||
@param baselineSnap setting for baseline snapping to pixels
|
||||
*/
|
||||
void setBaselineSnap(bool baselineSnap);
|
||||
|
||||
/** Whether edge pixels draw opaque or with partial transparency.
|
||||
*/
|
||||
Edging getEdging() const { return (Edging)fEdging; }
|
||||
|
||||
/** Requests, but does not require, that edge pixels draw opaque or with
|
||||
partial transparency.
|
||||
*/
|
||||
void setEdging(Edging edging);
|
||||
|
||||
/** Sets level of glyph outline adjustment.
|
||||
Does not check for valid values of hintingLevel.
|
||||
*/
|
||||
void setHinting(SkFontHinting hintingLevel);
|
||||
|
||||
/** Returns level of glyph outline adjustment.
|
||||
*/
|
||||
SkFontHinting getHinting() const { return (SkFontHinting)fHinting; }
|
||||
|
||||
/** Returns a font with the same attributes of this font, but with the specified size.
|
||||
Returns nullptr if size is less than zero, infinite, or NaN.
|
||||
|
||||
@param size EM size in local coordinate units
|
||||
@return initialized SkFont
|
||||
*/
|
||||
SkFont makeWithSize(SkScalar size) const;
|
||||
|
||||
/** Does not alter SkTypeface SkRefCnt.
|
||||
|
||||
@return non-null SkTypeface
|
||||
*/
|
||||
SkTypeface* getTypeface() const {
|
||||
SkASSERT(fTypeface);
|
||||
return fTypeface.get();
|
||||
}
|
||||
|
||||
/** Return EM size in local coordinate units.
|
||||
See https://skia.org/docs/user/coordinates/#local-coordinates .
|
||||
|
||||
@return EM size in local coordinate units
|
||||
*/
|
||||
SkScalar getSize() const { return fSize; }
|
||||
|
||||
/** Returns text scale on x-axis.
|
||||
Default value is 1.
|
||||
|
||||
@return text horizontal scale
|
||||
*/
|
||||
SkScalar getScaleX() const { return fScaleX; }
|
||||
|
||||
/** Returns text skew on x-axis.
|
||||
Default value is zero.
|
||||
|
||||
@return additional shear on x-axis relative to y-axis
|
||||
*/
|
||||
SkScalar getSkewX() const { return fSkewX; }
|
||||
|
||||
/** Increases SkTypeface SkRefCnt by one.
|
||||
|
||||
@return A non-null SkTypeface.
|
||||
*/
|
||||
sk_sp<SkTypeface> refTypeface() const {
|
||||
SkASSERT(fTypeface);
|
||||
return fTypeface;
|
||||
}
|
||||
|
||||
/** Sets SkTypeface to typeface, decreasing SkRefCnt of the previous SkTypeface.
|
||||
Pass nullptr to clear SkTypeface and use an empty typeface (which draws nothing).
|
||||
Increments tf SkRefCnt by one.
|
||||
|
||||
@param tf font and style used to draw text
|
||||
*/
|
||||
void setTypeface(sk_sp<SkTypeface> tf);
|
||||
|
||||
/** Sets the EM size in local coordinate units.
|
||||
See https://skia.org/docs/user/coordinates/#local-coordinates .
|
||||
Has no effect if textSize is not greater than or equal to zero.
|
||||
|
||||
@param textSize EM size in local coordinate units
|
||||
*/
|
||||
void setSize(SkScalar textSize);
|
||||
|
||||
/** Sets text scale on x-axis.
|
||||
Default value is 1.
|
||||
|
||||
@param scaleX text horizontal scale
|
||||
*/
|
||||
void setScaleX(SkScalar scaleX);
|
||||
|
||||
/** Sets text skew on x-axis.
|
||||
Default value is zero.
|
||||
|
||||
@param skewX additional shear on x-axis relative to y-axis
|
||||
*/
|
||||
void setSkewX(SkScalar skewX);
|
||||
|
||||
/** Converts text into glyph indices.
|
||||
Returns the number of glyph indices represented by text.
|
||||
SkTextEncoding specifies how text represents characters or glyphs.
|
||||
glyphs may be empty, to compute the glyph count.
|
||||
|
||||
Does not check text for valid character codes or valid glyph indices.
|
||||
|
||||
If byteLength equals zero, returns zero.
|
||||
If byteLength includes a partial character, the partial character is ignored.
|
||||
|
||||
If encoding is SkTextEncoding::kUTF8 and text contains an invalid UTF-8 sequence,
|
||||
zero is returned.
|
||||
|
||||
When encoding is SkTextEncoding::kUTF8, SkTextEncoding::kUTF16, or
|
||||
SkTextEncoding::kUTF32; then each Unicode codepoint is mapped to a
|
||||
single glyph. This function uses the default character-to-glyph
|
||||
mapping from the SkTypeface and maps characters not found in the
|
||||
SkTypeface to zero.
|
||||
|
||||
If glyphs.size() is not sufficient to store all the glyphs, no glyphs are copied.
|
||||
The total glyph count is returned for subsequent buffer reallocation.
|
||||
|
||||
@param text character storage encoded with SkTextEncoding
|
||||
@param byteLength length of character storage in bytes
|
||||
@param glyphs storage for glyph indices; may be empty
|
||||
@return number of glyphs represented by text of length byteLength
|
||||
*/
|
||||
size_t textToGlyphs(const void* text, size_t byteLength, SkTextEncoding encoding,
|
||||
SkSpan<SkGlyphID> glyphs) const;
|
||||
|
||||
/** Returns glyph index for Unicode character.
|
||||
|
||||
If the character is not supported by the SkTypeface, returns 0.
|
||||
|
||||
@param uni Unicode character
|
||||
@return glyph index
|
||||
*/
|
||||
SkGlyphID unicharToGlyph(SkUnichar uni) const;
|
||||
|
||||
void unicharsToGlyphs(SkSpan<const SkUnichar> src, SkSpan<SkGlyphID> dst) const;
|
||||
|
||||
/** Returns number of glyphs represented by text.
|
||||
|
||||
If encoding is SkTextEncoding::kUTF8, SkTextEncoding::kUTF16, or
|
||||
SkTextEncoding::kUTF32; then each Unicode codepoint is mapped to a
|
||||
single glyph.
|
||||
|
||||
@param text character storage encoded with SkTextEncoding
|
||||
@param byteLength length of character storage in bytes
|
||||
@return number of glyphs represented by text of length byteLength
|
||||
*/
|
||||
size_t countText(const void* text, size_t byteLength, SkTextEncoding encoding) const {
|
||||
return this->textToGlyphs(text, byteLength, encoding, {});
|
||||
}
|
||||
|
||||
/** Returns the advance width of text.
|
||||
The advance is the normal distance to move before drawing additional text.
|
||||
Returns the bounding box of text if bounds is not nullptr.
|
||||
|
||||
@param text character storage encoded with SkTextEncoding
|
||||
@param byteLength length of character storage in bytes
|
||||
@param bounds returns bounding box relative to (0, 0) if not nullptr
|
||||
@return the sum of the default advance widths
|
||||
*/
|
||||
SkScalar measureText(const void* text, size_t byteLength, SkTextEncoding encoding,
|
||||
SkRect* bounds = nullptr) const {
|
||||
return this->measureText(text, byteLength, encoding, bounds, nullptr);
|
||||
}
|
||||
|
||||
/** Returns the advance width of text.
|
||||
The advance is the normal distance to move before drawing additional text.
|
||||
Returns the bounding box of text if bounds is not nullptr. The paint
|
||||
stroke settings, mask filter, or path effect may modify the bounds.
|
||||
|
||||
@param text character storage encoded with SkTextEncoding
|
||||
@param byteLength length of character storage in bytes
|
||||
@param bounds returns bounding box relative to (0, 0) if not nullptr
|
||||
@param paint optional; may be nullptr
|
||||
@return the sum of the default advance widths
|
||||
*/
|
||||
SkScalar measureText(const void* text, size_t byteLength, SkTextEncoding encoding,
|
||||
SkRect* bounds, const SkPaint* paint) const;
|
||||
|
||||
/** Returns an SkStrikeRef for this font's current settings.
|
||||
|
||||
An SkStrikeRef caches the resolved strike (font metrics engine), avoiding the overhead
|
||||
of descriptor construction, hashing, and global cache lookup on each glyph query.
|
||||
This is useful when making many glyph metric calls (e.g. getWidths) with the same
|
||||
font configuration.
|
||||
|
||||
The returned SkStrikeRef is independent of this SkFont; subsequent changes to this
|
||||
SkFont do not affect it. Create a new SkStrikeRef after changing font properties.
|
||||
|
||||
@return an SkStrikeRef for the current font settings
|
||||
*/
|
||||
SkStrikeRef makeStrikeRef() const;
|
||||
|
||||
/** Retrieves the advance and bounds for each glyph in glyphs.
|
||||
widths receives min(widths.size(), glyphs.size()) values.
|
||||
bounds receives min(bounds.size(), glyphs.size()) values.
|
||||
|
||||
@param glyphs array of glyph indices to be measured
|
||||
@param widths returns text advances for each glyph
|
||||
@param bounds returns bounds for each glyph relative to (0, 0)
|
||||
@param paint optional, specifies stroking, SkPathEffect and SkMaskFilter
|
||||
*/
|
||||
void getWidthsBounds(SkSpan<const SkGlyphID> glyphs, SkSpan<SkScalar> widths, SkSpan<SkRect> bounds,
|
||||
const SkPaint* paint) const;
|
||||
|
||||
/** Retrieves the advance and bounds for each glyph in glyphs.
|
||||
widths receives min(widths.size(), glyphs.size()) values.
|
||||
|
||||
@param glyphs array of glyph indices to be measured
|
||||
@param widths returns text advances for each glyph
|
||||
*/
|
||||
void getWidths(SkSpan<const SkGlyphID> glyphs, SkSpan<SkScalar> widths) const {
|
||||
this->getWidthsBounds(glyphs, widths, {}, nullptr);
|
||||
}
|
||||
SkScalar getWidth(SkGlyphID glyph) const {
|
||||
SkScalar width;
|
||||
this->getWidthsBounds({&glyph, 1}, {&width, 1}, {}, nullptr);
|
||||
return width;
|
||||
}
|
||||
|
||||
/** Retrieves the bounds for each glyph in glyphs.
|
||||
bounds receives min(bounds.size(), glyphs.size()) values.
|
||||
If paint is not nullptr, its stroking, SkPathEffect, and SkMaskFilter fields are respected.
|
||||
|
||||
@param glyphs array of glyph indices to be measured
|
||||
@param bounds returns bounds for each glyph relative to (0, 0); may be nullptr
|
||||
@param paint optional, specifies stroking, SkPathEffect, and SkMaskFilter
|
||||
*/
|
||||
void getBounds(SkSpan<const SkGlyphID> glyphs, SkSpan<SkRect> bounds,
|
||||
const SkPaint* paint) const {
|
||||
this->getWidthsBounds(glyphs, {}, bounds, paint);
|
||||
}
|
||||
SkRect getBounds(SkGlyphID glyph, const SkPaint* paint) const {
|
||||
SkRect bounds;
|
||||
this->getBounds({&glyph, 1}, {&bounds, 1}, paint);
|
||||
return bounds;
|
||||
}
|
||||
|
||||
/** Retrieves the positions for each glyph, beginning at the specified origin.
|
||||
pos receives min(pos.size(), glyphs.size()) values.
|
||||
|
||||
@param glyphs array of glyph indices to be positioned
|
||||
@param pos returns glyphs positions
|
||||
@param origin location of the first glyph. Defaults to {0, 0}.
|
||||
*/
|
||||
void getPos(SkSpan<const SkGlyphID> glyphs, SkSpan<SkPoint> pos, SkPoint origin = {0, 0}) const;
|
||||
|
||||
/** Retrieves the x-positions for each glyph, beginning at the specified origin.
|
||||
xpos receives min(xpos.size(), glyphs.size()) values.
|
||||
|
||||
@param glyphs array of glyph indices to be positioned
|
||||
@param xpos returns glyphs x-positions
|
||||
@param origin x-position of the first glyph. Defaults to 0.
|
||||
*/
|
||||
void getXPos(SkSpan<const SkGlyphID> glyphs, SkSpan<SkScalar> xpos, SkScalar origin = 0) const;
|
||||
|
||||
/** Returns intervals [start, end] describing lines parallel to the advance that intersect
|
||||
* with the glyphs.
|
||||
*
|
||||
* @param glyphs the glyphs to intersect
|
||||
* @param pos the position of each glyph
|
||||
* @param top the top of the line intersecting
|
||||
* @param bottom the bottom of the line intersecting
|
||||
@return array of pairs of x values [start, end]. May be empty.
|
||||
*/
|
||||
std::vector<SkScalar> getIntercepts(SkSpan<const SkGlyphID> glyphs,
|
||||
SkSpan<const SkPoint> pos,
|
||||
SkScalar top, SkScalar bottom,
|
||||
const SkPaint* = nullptr) const;
|
||||
|
||||
/*
|
||||
* If the specified glyph can be represented as a path, return its path.
|
||||
* If it is not (e.g. it is represented with a bitmap) return {}.
|
||||
*
|
||||
* Note: an 'empty' glyph (e.g. what a space " " character might map to) can return
|
||||
* a path, but that path may have zero contours.
|
||||
*/
|
||||
std::optional<SkPath> getPath(SkGlyphID glyphID) const;
|
||||
|
||||
/** Returns path corresponding to glyph array.
|
||||
|
||||
@param glyphIDs array of glyph indices
|
||||
@param glyphPathProc function returning one glyph description as path
|
||||
@param ctx function context
|
||||
*/
|
||||
void getPaths(SkSpan<const SkGlyphID> glyphIDs,
|
||||
void (*glyphPathProc)(const SkPath* pathOrNull, const SkMatrix& mx, void* ctx),
|
||||
void* ctx) const;
|
||||
|
||||
/** Returns SkFontMetrics associated with SkTypeface.
|
||||
The return value is the recommended spacing between lines: the sum of metrics
|
||||
descent, ascent, and leading.
|
||||
If metrics is not nullptr, SkFontMetrics is copied to metrics.
|
||||
Results are scaled by text size but does not take into account
|
||||
dimensions required by text scale, text skew, fake bold,
|
||||
style stroke, and SkPathEffect.
|
||||
|
||||
@param metrics storage for SkFontMetrics; may be nullptr
|
||||
@return recommended spacing between lines
|
||||
*/
|
||||
SkScalar getMetrics(SkFontMetrics* metrics) const;
|
||||
|
||||
/** Returns the recommended spacing between lines: the sum of metrics
|
||||
descent, ascent, and leading.
|
||||
Result is scaled by text size but does not take into account
|
||||
dimensions required by stroking and SkPathEffect.
|
||||
Returns the same result as getMetrics().
|
||||
|
||||
@return recommended spacing between lines
|
||||
*/
|
||||
SkScalar getSpacing() const { return this->getMetrics(nullptr); }
|
||||
|
||||
/** Dumps fields of the font to SkDebugf. May change its output over time, so clients should
|
||||
* not rely on this for anything specific. Used to aid in debugging.
|
||||
*/
|
||||
void dump() const;
|
||||
|
||||
using sk_is_trivially_relocatable = std::true_type;
|
||||
|
||||
private:
|
||||
enum PrivFlags {
|
||||
kForceAutoHinting_PrivFlag = 1 << 0,
|
||||
kEmbeddedBitmaps_PrivFlag = 1 << 1,
|
||||
kSubpixel_PrivFlag = 1 << 2,
|
||||
kLinearMetrics_PrivFlag = 1 << 3,
|
||||
kEmbolden_PrivFlag = 1 << 4,
|
||||
kBaselineSnap_PrivFlag = 1 << 5,
|
||||
};
|
||||
|
||||
static constexpr unsigned kAllFlags = kForceAutoHinting_PrivFlag
|
||||
| kEmbeddedBitmaps_PrivFlag
|
||||
| kSubpixel_PrivFlag
|
||||
| kLinearMetrics_PrivFlag
|
||||
| kEmbolden_PrivFlag
|
||||
| kBaselineSnap_PrivFlag;
|
||||
|
||||
sk_sp<SkTypeface> fTypeface;
|
||||
SkScalar fSize;
|
||||
SkScalar fScaleX;
|
||||
SkScalar fSkewX;
|
||||
uint8_t fFlags;
|
||||
uint8_t fEdging;
|
||||
uint8_t fHinting;
|
||||
|
||||
static_assert(::sk_is_trivially_relocatable<decltype(fTypeface)>::value);
|
||||
|
||||
SkScalar setupForAsPaths(SkPaint*);
|
||||
bool hasSomeAntiAliasing() const;
|
||||
|
||||
friend class SkFontPriv;
|
||||
friend class skcpu::GlyphRunListPainter;
|
||||
friend class SkStrikeSpec;
|
||||
friend class SkRemoteGlyphCacheTest;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Copyright 2017 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkFontArguments_DEFINED
|
||||
#define SkFontArguments_DEFINED
|
||||
|
||||
#include "include/core/SkColor.h"
|
||||
#include "include/core/SkFourByteTag.h"
|
||||
#include "include/core/SkTypes.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
|
||||
/** Represents a set of actual arguments for a font. */
|
||||
struct SkFontArguments {
|
||||
struct VariationPosition {
|
||||
struct Coordinate {
|
||||
static constexpr SkFourByteTag wght = SkSetFourByteTag('w', 'g', 'h', 't');
|
||||
static constexpr SkFourByteTag wdth = SkSetFourByteTag('w', 'd', 't', 'h');
|
||||
static constexpr SkFourByteTag slnt = SkSetFourByteTag('s', 'l', 'n', 't');
|
||||
static constexpr SkFourByteTag ital = SkSetFourByteTag('i', 't', 'a', 'l');
|
||||
static constexpr SkFourByteTag opsz = SkSetFourByteTag('o', 'p', 's', 'z');
|
||||
SkFourByteTag axis;
|
||||
float value;
|
||||
};
|
||||
const Coordinate* coordinates;
|
||||
int coordinateCount;
|
||||
};
|
||||
|
||||
/** Specify a palette to use and overrides for palette entries.
|
||||
*
|
||||
* `overrides` is a list of pairs of palette entry index and color.
|
||||
* The overriden palette entries will use the associated color.
|
||||
* Override pairs with palette entry indices out of range will not be applied.
|
||||
* Later override entries override earlier ones.
|
||||
*/
|
||||
struct Palette {
|
||||
struct Override {
|
||||
uint16_t index;
|
||||
SkColor color;
|
||||
};
|
||||
int index;
|
||||
const Override* overrides;
|
||||
int overrideCount;
|
||||
};
|
||||
|
||||
SkFontArguments()
|
||||
: fCollectionIndex(0)
|
||||
, fVariationDesignPosition{nullptr, 0}
|
||||
, fPalette{0, nullptr, 0} {}
|
||||
|
||||
/** Specify the index of the desired font.
|
||||
*
|
||||
* Font formats like ttc, dfont, cff, cid, pfr, t42, t1, and fon may actually be indexed
|
||||
* collections of fonts.
|
||||
*/
|
||||
SkFontArguments& setCollectionIndex(int collectionIndex) {
|
||||
fCollectionIndex = collectionIndex;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Specify a position in the variation design space.
|
||||
*
|
||||
* Any axis not specified will use the default value.
|
||||
* Any specified axis not actually present in the font will be ignored.
|
||||
*
|
||||
* @param position not copied. The value must remain valid for life of SkFontArguments.
|
||||
*/
|
||||
SkFontArguments& setVariationDesignPosition(VariationPosition position) {
|
||||
fVariationDesignPosition.coordinates = position.coordinates;
|
||||
fVariationDesignPosition.coordinateCount = position.coordinateCount;
|
||||
return *this;
|
||||
}
|
||||
|
||||
int getCollectionIndex() const {
|
||||
return fCollectionIndex;
|
||||
}
|
||||
|
||||
VariationPosition getVariationDesignPosition() const {
|
||||
return fVariationDesignPosition;
|
||||
}
|
||||
|
||||
SkFontArguments& setPalette(Palette palette) {
|
||||
fPalette.index = palette.index;
|
||||
fPalette.overrides = palette.overrides;
|
||||
fPalette.overrideCount = palette.overrideCount;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Palette getPalette() const { return fPalette; }
|
||||
|
||||
SkFontArguments& setSyntheticBold(std::optional<bool> bold) {
|
||||
fSyntheticBold = bold;
|
||||
return *this;
|
||||
}
|
||||
std::optional<bool> getSyntheticBold() const { return fSyntheticBold; }
|
||||
|
||||
SkFontArguments& setSyntheticOblique(std::optional<bool> oblique) {
|
||||
fSyntheticOblique = oblique;
|
||||
return *this;
|
||||
}
|
||||
std::optional<bool> getSyntheticOblique() const { return fSyntheticOblique; }
|
||||
|
||||
private:
|
||||
int fCollectionIndex;
|
||||
VariationPosition fVariationDesignPosition;
|
||||
Palette fPalette;
|
||||
std::optional<bool> fSyntheticBold;
|
||||
std::optional<bool> fSyntheticOblique;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* Copyright 2018 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkFontMetrics_DEFINED
|
||||
#define SkFontMetrics_DEFINED
|
||||
|
||||
#include "include/core/SkScalar.h"
|
||||
#include "include/private/base/SkTo.h"
|
||||
|
||||
/** \class SkFontMetrics
|
||||
The metrics of an SkFont.
|
||||
The metric values are consistent with the Skia y-down coordinate system.
|
||||
*/
|
||||
struct SK_API SkFontMetrics {
|
||||
bool operator==(const SkFontMetrics& that) const {
|
||||
return
|
||||
this->fFlags == that.fFlags &&
|
||||
this->fTop == that.fTop &&
|
||||
this->fAscent == that.fAscent &&
|
||||
this->fDescent == that.fDescent &&
|
||||
this->fBottom == that.fBottom &&
|
||||
this->fLeading == that.fLeading &&
|
||||
this->fAvgCharWidth == that.fAvgCharWidth &&
|
||||
this->fMaxCharWidth == that.fMaxCharWidth &&
|
||||
this->fXMin == that.fXMin &&
|
||||
this->fXMax == that.fXMax &&
|
||||
this->fXHeight == that.fXHeight &&
|
||||
this->fCapHeight == that.fCapHeight &&
|
||||
this->fUnderlineThickness == that.fUnderlineThickness &&
|
||||
this->fUnderlinePosition == that.fUnderlinePosition &&
|
||||
this->fStrikeoutThickness == that.fStrikeoutThickness &&
|
||||
this->fStrikeoutPosition == that.fStrikeoutPosition;
|
||||
}
|
||||
|
||||
/** \enum FontMetricsFlags
|
||||
FontMetricsFlags indicate when certain metrics are valid;
|
||||
the underline or strikeout metrics may be valid and zero.
|
||||
Fonts with embedded bitmaps may not have valid underline or strikeout metrics.
|
||||
*/
|
||||
enum FontMetricsFlags {
|
||||
kUnderlineThicknessIsValid_Flag = 1 << 0, //!< set if fUnderlineThickness is valid
|
||||
kUnderlinePositionIsValid_Flag = 1 << 1, //!< set if fUnderlinePosition is valid
|
||||
kStrikeoutThicknessIsValid_Flag = 1 << 2, //!< set if fStrikeoutThickness is valid
|
||||
kStrikeoutPositionIsValid_Flag = 1 << 3, //!< set if fStrikeoutPosition is valid
|
||||
kBoundsInvalid_Flag = 1 << 4, //!< set if fTop, fBottom, fXMin, fXMax invalid
|
||||
};
|
||||
|
||||
uint32_t fFlags; //!< FontMetricsFlags indicating which metrics are valid
|
||||
SkScalar fTop; //!< greatest extent above origin of any glyph bounding box, typically negative; deprecated with variable fonts
|
||||
SkScalar fAscent; //!< distance to reserve above baseline, typically negative
|
||||
SkScalar fDescent; //!< distance to reserve below baseline, typically positive
|
||||
SkScalar fBottom; //!< greatest extent below origin of any glyph bounding box, typically positive; deprecated with variable fonts
|
||||
SkScalar fLeading; //!< distance to add between lines, typically positive or zero
|
||||
SkScalar fAvgCharWidth; //!< average character width, zero if unknown
|
||||
SkScalar fMaxCharWidth; //!< maximum character width, zero if unknown
|
||||
SkScalar fXMin; //!< greatest extent to left of origin of any glyph bounding box, typically negative; deprecated with variable fonts
|
||||
SkScalar fXMax; //!< greatest extent to right of origin of any glyph bounding box, typically positive; deprecated with variable fonts
|
||||
SkScalar fXHeight; //!< height of lower-case 'x', zero if unknown, typically negative
|
||||
SkScalar fCapHeight; //!< height of an upper-case letter, zero if unknown, typically negative
|
||||
SkScalar fUnderlineThickness; //!< underline thickness
|
||||
SkScalar fUnderlinePosition; //!< distance from baseline to top of stroke, typically positive
|
||||
SkScalar fStrikeoutThickness; //!< strikeout thickness
|
||||
SkScalar fStrikeoutPosition; //!< distance from baseline to bottom of stroke, typically negative
|
||||
|
||||
/** Returns true if SkFontMetrics has a valid underline thickness, and sets
|
||||
thickness to that value. If the underline thickness is not valid,
|
||||
return false, and ignore thickness.
|
||||
|
||||
@param thickness storage for underline width
|
||||
@return true if font specifies underline width
|
||||
*/
|
||||
bool hasUnderlineThickness(SkScalar* thickness) const {
|
||||
if (SkToBool(fFlags & kUnderlineThicknessIsValid_Flag)) {
|
||||
*thickness = fUnderlineThickness;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Returns true if SkFontMetrics has a valid underline position, and sets
|
||||
position to that value. If the underline position is not valid,
|
||||
return false, and ignore position.
|
||||
|
||||
@param position storage for underline position
|
||||
@return true if font specifies underline position
|
||||
*/
|
||||
bool hasUnderlinePosition(SkScalar* position) const {
|
||||
if (SkToBool(fFlags & kUnderlinePositionIsValid_Flag)) {
|
||||
*position = fUnderlinePosition;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Returns true if SkFontMetrics has a valid strikeout thickness, and sets
|
||||
thickness to that value. If the underline thickness is not valid,
|
||||
return false, and ignore thickness.
|
||||
|
||||
@param thickness storage for strikeout width
|
||||
@return true if font specifies strikeout width
|
||||
*/
|
||||
bool hasStrikeoutThickness(SkScalar* thickness) const {
|
||||
if (SkToBool(fFlags & kStrikeoutThicknessIsValid_Flag)) {
|
||||
*thickness = fStrikeoutThickness;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Returns true if SkFontMetrics has a valid strikeout position, and sets
|
||||
position to that value. If the underline position is not valid,
|
||||
return false, and ignore position.
|
||||
|
||||
@param position storage for strikeout position
|
||||
@return true if font specifies strikeout position
|
||||
*/
|
||||
bool hasStrikeoutPosition(SkScalar* position) const {
|
||||
if (SkToBool(fFlags & kStrikeoutPositionIsValid_Flag)) {
|
||||
*position = fStrikeoutPosition;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Returns true if SkFontMetrics has a valid fTop, fBottom, fXMin, and fXMax.
|
||||
If the bounds are not valid, return false.
|
||||
|
||||
@return true if font specifies maximum glyph bounds
|
||||
*/
|
||||
bool hasBounds() const {
|
||||
return !SkToBool(fFlags & kBoundsInvalid_Flag);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
* Copyright 2013 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkFontMgr_DEFINED
|
||||
#define SkFontMgr_DEFINED
|
||||
|
||||
#include "include/core/SkFontArguments.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/core/SkSpan.h"
|
||||
#include "include/core/SkTypes.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
class SkData;
|
||||
class SkFontStyle;
|
||||
class SkStreamAsset;
|
||||
class SkString;
|
||||
class SkTypeface;
|
||||
|
||||
class SK_API SkFontStyleSet : public SkRefCnt {
|
||||
public:
|
||||
virtual int count() = 0;
|
||||
virtual void getStyle(int index, SkFontStyle*, SkString* style) = 0;
|
||||
virtual sk_sp<SkTypeface> createTypeface(int index) = 0;
|
||||
virtual sk_sp<SkTypeface> matchStyle(const SkFontStyle& pattern) = 0;
|
||||
|
||||
static sk_sp<SkFontStyleSet> CreateEmpty();
|
||||
|
||||
protected:
|
||||
sk_sp<SkTypeface> matchStyleCSS3(const SkFontStyle& pattern);
|
||||
};
|
||||
|
||||
class SK_API SkFontMgr : public SkRefCnt {
|
||||
public:
|
||||
int countFamilies() const;
|
||||
void getFamilyName(int index, SkString* familyName) const;
|
||||
sk_sp<SkFontStyleSet> createStyleSet(int index) const;
|
||||
|
||||
/**
|
||||
* The caller must call unref() on the returned object.
|
||||
* Never returns NULL; will return an empty set if the name is not found.
|
||||
*
|
||||
* Passing nullptr as the parameter will return the default system family.
|
||||
* Note that most systems don't have a default system family, so passing nullptr will often
|
||||
* result in the empty set.
|
||||
*
|
||||
* It is possible that this will return a style set not accessible from
|
||||
* createStyleSet(int) due to hidden or auto-activated fonts.
|
||||
*/
|
||||
sk_sp<SkFontStyleSet> matchFamily(const char familyName[]) const;
|
||||
|
||||
/**
|
||||
* Find the closest matching typeface to the specified familyName and style
|
||||
* and return a ref to it. The caller must call unref() on the returned
|
||||
* object. Will return nullptr if no 'good' match is found.
|
||||
*
|
||||
* Passing |nullptr| as the parameter for |familyName| will return the
|
||||
* default system font.
|
||||
*
|
||||
* It is possible that this will return a style set not accessible from
|
||||
* createStyleSet(int) or matchFamily(const char[]) due to hidden or
|
||||
* auto-activated fonts.
|
||||
*/
|
||||
sk_sp<SkTypeface> matchFamilyStyle(const char familyName[], const SkFontStyle&) const;
|
||||
|
||||
/**
|
||||
* Use the system fallback to find a typeface for the given character.
|
||||
* Note that bcp47 is a combination of ISO 639, 15924, and 3166-1 codes,
|
||||
* so it is fine to just pass a ISO 639 here.
|
||||
*
|
||||
* Will return NULL if no family can be found for the character
|
||||
* in the system fallback.
|
||||
*
|
||||
* Passing |nullptr| as the parameter for |familyName| will return the
|
||||
* default system font.
|
||||
*
|
||||
* bcp47[0] is the least significant fallback, bcp47[bcp47Count-1] is the
|
||||
* most significant. If no specified bcp47 codes match, any font with the
|
||||
* requested character will be matched.
|
||||
*/
|
||||
sk_sp<SkTypeface> matchFamilyStyleCharacter(const char familyName[], const SkFontStyle&,
|
||||
const char* bcp47[], int bcp47Count,
|
||||
SkUnichar character) const;
|
||||
|
||||
struct Request {
|
||||
struct CMapEntry {
|
||||
SkUnichar character;
|
||||
SkUnichar variation; // Zero for default variation.
|
||||
};
|
||||
SkSpan<const CMapEntry> cmapEntries;
|
||||
|
||||
/**
|
||||
* bcp47[0] is the least significant fallback, bcp47[bcp47Count-1] is the most significant.
|
||||
* If no specified bcp47 codes match any font with the requested character will be matched.
|
||||
*/
|
||||
SkSpan<const char*> bcp47;
|
||||
|
||||
const char* familyName;
|
||||
|
||||
SkSpan<const SkFontArguments::VariationPosition::Coordinate> model;
|
||||
SkFontStyle fontStyleFromModel() const;
|
||||
static void SetModel(SkFontStyle s, SkFontArguments::VariationPosition::Coordinate(&m)[4]);
|
||||
|
||||
std::optional<bool> syntheticBold;
|
||||
std::optional<bool> syntheticOblique;
|
||||
};
|
||||
|
||||
/** The familyName must strongly match, everything else is tie breakers. */
|
||||
sk_sp<SkTypeface> match(const Request&) const;
|
||||
|
||||
/**
|
||||
* The first cmapEntry must match. Then matched by bcp47, then familyName,
|
||||
* then model (italic, slant, width, weight), with synthetics allowed or not.
|
||||
*/
|
||||
sk_sp<SkTypeface> fallback(const Request&) const;
|
||||
|
||||
/**
|
||||
* Create a typeface for the specified data and TTC index (pass 0 for none)
|
||||
* or NULL if the data is not recognized. The caller must call unref() on
|
||||
* the returned object if it is not null.
|
||||
*/
|
||||
sk_sp<SkTypeface> makeFromData(sk_sp<SkData>, int ttcIndex = 0) const;
|
||||
|
||||
/**
|
||||
* Create a typeface for the specified stream and TTC index
|
||||
* (pass 0 for none) or NULL if the stream is not recognized. The caller
|
||||
* must call unref() on the returned object if it is not null.
|
||||
*/
|
||||
sk_sp<SkTypeface> makeFromStream(std::unique_ptr<SkStreamAsset>, int ttcIndex = 0) const;
|
||||
|
||||
/* Experimental, API subject to change. */
|
||||
sk_sp<SkTypeface> makeFromStream(std::unique_ptr<SkStreamAsset>, const SkFontArguments&) const;
|
||||
|
||||
/**
|
||||
* Create a typeface for the specified fileName and TTC index
|
||||
* (pass 0 for none) or NULL if the file is not found, or its contents are
|
||||
* not recognized. The caller must call unref() on the returned object
|
||||
* if it is not null.
|
||||
*/
|
||||
sk_sp<SkTypeface> makeFromFile(const char path[], int ttcIndex = 0) const;
|
||||
|
||||
sk_sp<SkTypeface> legacyMakeTypeface(const char familyName[], SkFontStyle style) const;
|
||||
|
||||
/* Returns an empty font manager without any typeface dependencies */
|
||||
static sk_sp<SkFontMgr> RefEmpty();
|
||||
|
||||
protected:
|
||||
virtual int onCountFamilies() const = 0;
|
||||
virtual void onGetFamilyName(int index, SkString* familyName) const = 0;
|
||||
virtual sk_sp<SkFontStyleSet> onCreateStyleSet(int index)const = 0;
|
||||
|
||||
/** May return NULL if the name is not found. */
|
||||
virtual sk_sp<SkFontStyleSet> onMatchFamily(const char familyName[]) const = 0;
|
||||
|
||||
virtual sk_sp<SkTypeface> onMatchFamilyStyle(const char familyName[],
|
||||
const SkFontStyle&) const = 0;
|
||||
virtual sk_sp<SkTypeface> onMatchFamilyStyleCharacter(const char familyName[],
|
||||
const SkFontStyle&,
|
||||
const char* bcp47[], int bcp47Count,
|
||||
SkUnichar character) const = 0;
|
||||
virtual sk_sp<SkTypeface> onMatch(const Request&) const; // TODO: pure virtual
|
||||
virtual sk_sp<SkTypeface> onFallback(const Request&) const; // TODO: pure virtual
|
||||
|
||||
virtual sk_sp<SkTypeface> onMakeFromData(sk_sp<SkData>, int ttcIndex) const = 0;
|
||||
virtual sk_sp<SkTypeface> onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset>,
|
||||
int ttcIndex) const = 0;
|
||||
virtual sk_sp<SkTypeface> onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset>,
|
||||
const SkFontArguments&) const = 0;
|
||||
virtual sk_sp<SkTypeface> onMakeFromFile(const char path[], int ttcIndex) const = 0;
|
||||
|
||||
virtual sk_sp<SkTypeface> onLegacyMakeTypeface(const char familyName[], SkFontStyle) const = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright 2018 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkFontParameters_DEFINED
|
||||
#define SkFontParameters_DEFINED
|
||||
|
||||
#include "include/core/SkFourByteTag.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
struct SkFontParameters {
|
||||
struct Variation {
|
||||
// Parameters in a variation font axis.
|
||||
struct Axis {
|
||||
constexpr Axis() : tag(0), min(0), def(0), max(0), flags(0) {}
|
||||
constexpr Axis(SkFourByteTag tag, float min, float def, float max, bool hidden) :
|
||||
tag(tag), min(min), def(def), max(max), flags(hidden ? HIDDEN : 0) {}
|
||||
|
||||
// Four character identifier of the font axis (weight, width, slant, italic...).
|
||||
SkFourByteTag tag;
|
||||
// Minimum value supported by this axis.
|
||||
float min;
|
||||
// Default value set by this axis.
|
||||
float def;
|
||||
// Maximum value supported by this axis. The maximum can equal the minimum.
|
||||
float max;
|
||||
// Return whether this axis is recommended to be remain hidden in user interfaces.
|
||||
bool isHidden() const { return flags & HIDDEN; }
|
||||
// Set this axis to be remain hidden in user interfaces.
|
||||
void setHidden(bool hidden) { flags = hidden ? (flags | HIDDEN) : (flags & ~HIDDEN); }
|
||||
private:
|
||||
static constexpr uint16_t HIDDEN = 0x0001;
|
||||
// Attributes for a font axis.
|
||||
uint16_t flags;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright 2024 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SKFONTSCANNER_H_
|
||||
#define SKFONTSCANNER_H_
|
||||
|
||||
#include "include/core/SkFontArguments.h"
|
||||
#include "include/core/SkFontParameters.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/core/SkTypes.h"
|
||||
#include "include/private/base/SkFixed.h"
|
||||
#include "include/private/base/SkNoncopyable.h"
|
||||
#include "include/private/base/SkTArray.h"
|
||||
class SkFontStyle;
|
||||
class SkStreamAsset;
|
||||
class SkString;
|
||||
class SkTypeface;
|
||||
|
||||
class SkFontScanner : public SkNoncopyable {
|
||||
public:
|
||||
virtual ~SkFontScanner() = default;
|
||||
using AxisDefinitions = skia_private::STArray<4, SkFontParameters::Variation::Axis, true>;
|
||||
using VariationPosition = skia_private::STArray<4, SkFontArguments::VariationPosition::Coordinate, true>;
|
||||
|
||||
virtual bool scanFile(SkStreamAsset* stream, int* numFaces) const = 0;
|
||||
virtual bool scanFace(SkStreamAsset* stream, int faceIndex, int* numInstances) const = 0;
|
||||
/* instanceIndex 0 is the default instance, 1 to numInstances are the named instances. */
|
||||
virtual bool scanInstance(SkStreamAsset* stream,
|
||||
int faceIndex,
|
||||
int instanceIndex,
|
||||
SkString* name,
|
||||
SkFontStyle* style,
|
||||
bool* isFixedPitch,
|
||||
AxisDefinitions* axes,
|
||||
VariationPosition* position) const = 0;
|
||||
virtual sk_sp<SkTypeface> MakeFromStream(std::unique_ptr<SkStreamAsset> stream,
|
||||
const SkFontArguments& args) const = 0;
|
||||
virtual SkFourByteTag getFactoryId() const = 0;
|
||||
};
|
||||
|
||||
#endif // SKFONTSCANNER_H_
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright 2013 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkFontStyle_DEFINED
|
||||
#define SkFontStyle_DEFINED
|
||||
|
||||
#include "include/core/SkTypes.h"
|
||||
#include "include/private/base/SkTPin.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class SK_API SkFontStyle {
|
||||
public:
|
||||
enum Weight {
|
||||
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 {
|
||||
kUltraCondensed_Width = 1,
|
||||
kExtraCondensed_Width = 2,
|
||||
kCondensed_Width = 3,
|
||||
kSemiCondensed_Width = 4,
|
||||
kNormal_Width = 5,
|
||||
kSemiExpanded_Width = 6,
|
||||
kExpanded_Width = 7,
|
||||
kExtraExpanded_Width = 8,
|
||||
kUltraExpanded_Width = 9,
|
||||
};
|
||||
|
||||
enum Slant : uint8_t {
|
||||
kUpright_Slant,
|
||||
kItalic_Slant,
|
||||
kOblique_Slant,
|
||||
};
|
||||
|
||||
constexpr SkFontStyle(int weight, int width, Slant slant) : fValue(
|
||||
(SkTPin<int>(weight, kInvisible_Weight, kExtraBlack_Weight)) +
|
||||
(SkTPin<int>(width, kUltraCondensed_Width, kUltraExpanded_Width) << 16) +
|
||||
(SkTPin<int>(slant, kUpright_Slant, kOblique_Slant) << 24)
|
||||
) { }
|
||||
|
||||
constexpr SkFontStyle() : SkFontStyle{kNormal_Weight, kNormal_Width, kUpright_Slant} { }
|
||||
|
||||
bool operator==(const SkFontStyle& rhs) const {
|
||||
return fValue == rhs.fValue;
|
||||
}
|
||||
|
||||
int weight() const { return fValue & 0xFFFF; }
|
||||
int width() const { return (fValue >> 16) & 0xFF; }
|
||||
Slant slant() const { return (Slant)((fValue >> 24) & 0xFF); }
|
||||
|
||||
static constexpr SkFontStyle Normal() {
|
||||
return SkFontStyle(kNormal_Weight, kNormal_Width, kUpright_Slant);
|
||||
}
|
||||
static constexpr SkFontStyle Bold() {
|
||||
return SkFontStyle(kBold_Weight, kNormal_Width, kUpright_Slant);
|
||||
}
|
||||
static constexpr SkFontStyle Italic() {
|
||||
return SkFontStyle(kNormal_Weight, kNormal_Width, kItalic_Slant );
|
||||
}
|
||||
static constexpr SkFontStyle BoldItalic() {
|
||||
return SkFontStyle(kBold_Weight, kNormal_Width, kItalic_Slant );
|
||||
}
|
||||
|
||||
private:
|
||||
friend class SkTypefaceProxyPrototype; // To serialize fValue
|
||||
int32_t fValue;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright 2018 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkFontTypes_DEFINED
|
||||
#define SkFontTypes_DEFINED
|
||||
|
||||
enum class SkTextEncoding {
|
||||
kUTF8, //!< uses bytes to represent UTF-8 or ASCII
|
||||
kUTF16, //!< uses two byte words to represent most of Unicode
|
||||
kUTF32, //!< uses four byte words to represent all of Unicode
|
||||
kGlyphID, //!< uses two byte words to represent glyph indices
|
||||
};
|
||||
|
||||
enum class SkFontHinting {
|
||||
kNone, //!< glyph outlines unchanged
|
||||
kSlight, //!< minimal modification to improve constrast
|
||||
kNormal, //!< glyph outlines modified to improve constrast
|
||||
kFull, //!< modifies glyph outlines for maximum constrast
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright 2024 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkFourByteTag_DEFINED
|
||||
#define SkFourByteTag_DEFINED
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
using SkFourByteTag = uint32_t;
|
||||
|
||||
static inline constexpr SkFourByteTag SkSetFourByteTag(char a, char b, char c, char d) {
|
||||
return (((uint32_t)a << 24) | ((uint32_t)b << 16) | ((uint32_t)c << 8) | (uint32_t)d);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
* 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 SkGraphics_DEFINED
|
||||
#define SkGraphics_DEFINED
|
||||
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/private/base/SkAPI.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
class SkData;
|
||||
class SkImageGenerator;
|
||||
class SkOpenTypeSVGDecoder;
|
||||
class SkTraceMemoryDump;
|
||||
|
||||
class SK_API SkGraphics {
|
||||
public:
|
||||
/**
|
||||
* Call this at process initialization time if your environment does not
|
||||
* permit static global initializers that execute code.
|
||||
* Init() is thread-safe and idempotent.
|
||||
*/
|
||||
static void Init();
|
||||
|
||||
/**
|
||||
* Return the max number of bytes that should be used by the font cache.
|
||||
* If the cache needs to allocate more, it will purge previous entries.
|
||||
* This max can be changed by calling SetFontCacheLimit().
|
||||
*/
|
||||
static size_t GetFontCacheLimit();
|
||||
|
||||
/**
|
||||
* Specify the max number of bytes that should be used by the font cache.
|
||||
* If the cache needs to allocate more, it will purge previous entries.
|
||||
*
|
||||
* This function returns the previous setting, as if GetFontCacheLimit()
|
||||
* had be called before the new limit was set.
|
||||
*/
|
||||
static size_t SetFontCacheLimit(size_t bytes);
|
||||
|
||||
/**
|
||||
* Return the number of bytes currently used by the font cache.
|
||||
*/
|
||||
static size_t GetFontCacheUsed();
|
||||
|
||||
/**
|
||||
* Return the number of entries in the font cache.
|
||||
* A cache "entry" is associated with each typeface + pointSize + matrix.
|
||||
*/
|
||||
static int GetFontCacheCountUsed();
|
||||
|
||||
/**
|
||||
* Return the current limit to the number of entries in the font cache.
|
||||
* A cache "entry" is associated with each typeface + pointSize + matrix.
|
||||
*/
|
||||
static int GetFontCacheCountLimit();
|
||||
|
||||
/**
|
||||
* Set the limit to the number of entries in the font cache, and return
|
||||
* the previous value. If this new value is lower than the previous,
|
||||
* it will automatically try to purge entries to meet the new limit.
|
||||
*/
|
||||
static int SetFontCacheCountLimit(int count);
|
||||
|
||||
/**
|
||||
* Return the current limit to the number of entries in the typeface cache.
|
||||
* A cache "entry" is associated with each typeface.
|
||||
*/
|
||||
static int GetTypefaceCacheCountLimit();
|
||||
|
||||
/**
|
||||
* Set the limit to the number of entries in the typeface cache, and return
|
||||
* the previous value. Changes to this only take effect the next time
|
||||
* each cache object is modified.
|
||||
*/
|
||||
static int SetTypefaceCacheCountLimit(int count);
|
||||
|
||||
/**
|
||||
* For debugging purposes, this will attempt to purge the font cache. It
|
||||
* does not change the limit, but will cause subsequent font measures and
|
||||
* draws to be recreated, since they will no longer be in the cache.
|
||||
*/
|
||||
static void PurgeFontCache();
|
||||
|
||||
/**
|
||||
* If the strike cache is above the cache limit, attempt to purge strikes
|
||||
* with pinners. This should be called after clients release locks on
|
||||
* pinned strikes.
|
||||
*/
|
||||
static void PurgePinnedFontCache();
|
||||
|
||||
/**
|
||||
* This function returns the memory used for temporary images and other resources.
|
||||
*/
|
||||
static size_t GetResourceCacheTotalBytesUsed();
|
||||
|
||||
/**
|
||||
* These functions get/set the memory usage limit for the resource cache, used for temporary
|
||||
* bitmaps and other resources. Entries are purged from the cache when the memory useage
|
||||
* exceeds this limit.
|
||||
*/
|
||||
static size_t GetResourceCacheTotalByteLimit();
|
||||
static size_t SetResourceCacheTotalByteLimit(size_t newLimit);
|
||||
|
||||
/**
|
||||
* For debugging purposes, this will attempt to purge the resource cache. It
|
||||
* does not change the limit.
|
||||
*/
|
||||
static void PurgeResourceCache();
|
||||
|
||||
/**
|
||||
* When the cachable entry is very lage (e.g. a large scaled bitmap), adding it to the cache
|
||||
* can cause most/all of the existing entries to be purged. To avoid the, the client can set
|
||||
* a limit for a single allocation. If a cacheable entry would have been cached, but its size
|
||||
* exceeds this limit, then we do not attempt to cache it at all.
|
||||
*
|
||||
* Zero is the default value, meaning we always attempt to cache entries.
|
||||
*/
|
||||
static size_t GetResourceCacheSingleAllocationByteLimit();
|
||||
static size_t SetResourceCacheSingleAllocationByteLimit(size_t newLimit);
|
||||
|
||||
/**
|
||||
* Dumps memory usage of caches using the SkTraceMemoryDump interface. See SkTraceMemoryDump
|
||||
* for usage of this method.
|
||||
*/
|
||||
static void DumpMemoryStatistics(SkTraceMemoryDump* dump);
|
||||
|
||||
/**
|
||||
* Free as much globally cached memory as possible. This will purge all private caches in Skia,
|
||||
* including font and image caches.
|
||||
*
|
||||
* If there are caches associated with GPU context, those will not be affected by this call.
|
||||
*/
|
||||
static void PurgeAllCaches();
|
||||
|
||||
using ImageGeneratorFromEncodedDataFactory =
|
||||
std::unique_ptr<SkImageGenerator> (*)(sk_sp<const SkData>);
|
||||
|
||||
/**
|
||||
* To instantiate images from encoded data, first looks at this runtime function-ptr. If it
|
||||
* exists, it is called to create an SkImageGenerator from SkData. If there is no function-ptr
|
||||
* or there is, but it returns NULL, then skia will call its internal default implementation.
|
||||
*
|
||||
* Returns the previous factory (which could be NULL).
|
||||
*/
|
||||
static ImageGeneratorFromEncodedDataFactory
|
||||
SetImageGeneratorFromEncodedDataFactory(ImageGeneratorFromEncodedDataFactory);
|
||||
|
||||
/**
|
||||
* To draw OpenType SVG data, Skia will look at this runtime function pointer. If this function
|
||||
* pointer is set, the SkTypeface implementations which support OpenType SVG will call this
|
||||
* function to create an SkOpenTypeSVGDecoder to decode the OpenType SVG and draw it as needed.
|
||||
* If this function is not set, the SkTypeface implementations will generally not support
|
||||
* OpenType SVG and attempt to use other glyph representations if available.
|
||||
*/
|
||||
using OpenTypeSVGDecoderFactory =
|
||||
std::unique_ptr<SkOpenTypeSVGDecoder> (*)(const uint8_t* svg, size_t length);
|
||||
static OpenTypeSVGDecoderFactory SetOpenTypeSVGDecoderFactory(OpenTypeSVGDecoderFactory);
|
||||
static OpenTypeSVGDecoderFactory GetOpenTypeSVGDecoderFactory();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,918 @@
|
|||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkImage_DEFINED
|
||||
#define SkImage_DEFINED
|
||||
|
||||
#include "include/core/SkAlphaType.h"
|
||||
#include "include/core/SkImageInfo.h"
|
||||
#include "include/core/SkRect.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/core/SkSize.h"
|
||||
#include "include/private/base/SkAPI.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
class GrDirectContext;
|
||||
class SkBitmap;
|
||||
class SkColorSpace;
|
||||
class SkData;
|
||||
class SkImage;
|
||||
class SkImageFilter;
|
||||
class SkImageGenerator;
|
||||
class SkMatrix;
|
||||
class SkMipmap;
|
||||
class SkPaint;
|
||||
class SkPicture;
|
||||
class SkPixmap;
|
||||
class SkRecorder;
|
||||
class SkShader;
|
||||
class SkSurfaceProps;
|
||||
enum SkColorType : int;
|
||||
enum class SkTextureCompressionType;
|
||||
enum class SkTileMode;
|
||||
|
||||
struct SkIPoint;
|
||||
struct SkSamplingOptions;
|
||||
|
||||
namespace SkImages {
|
||||
|
||||
/** Caller data passed to RasterReleaseProc; may be nullptr. */
|
||||
using ReleaseContext = void*;
|
||||
/** Function called when SkImage no longer shares pixels. ReleaseContext is
|
||||
provided by caller when SkImage is created, and may be nullptr.
|
||||
*/
|
||||
using RasterReleaseProc = void(const void* pixels, ReleaseContext);
|
||||
|
||||
/** Creates a CPU-backed SkImage from bitmap, sharing or copying bitmap pixels. If the bitmap
|
||||
is marked immutable, and its pixel memory is shareable, it may be shared
|
||||
instead of copied.
|
||||
|
||||
SkImage is returned if bitmap is valid. Valid SkBitmap parameters include:
|
||||
dimensions are greater than zero;
|
||||
each dimension fits in 29 bits;
|
||||
SkColorType and SkAlphaType are valid, and SkColorType is not kUnknown_SkColorType;
|
||||
row bytes are large enough to hold one row of pixels;
|
||||
pixel address is not nullptr.
|
||||
|
||||
@param bitmap SkImageInfo, row bytes, and pixels
|
||||
@return created SkImage, or nullptr
|
||||
*/
|
||||
SK_API sk_sp<SkImage> RasterFromBitmap(const SkBitmap& bitmap);
|
||||
|
||||
/** Creates a CPU-backed SkImage from compressed data.
|
||||
|
||||
This method will decompress the compressed data and create an image wrapping
|
||||
it. Any mipmap levels present in the compressed data are discarded.
|
||||
|
||||
@param data compressed data to store in SkImage
|
||||
@param width width of full SkImage
|
||||
@param height height of full SkImage
|
||||
@param type type of compression used
|
||||
@return created SkImage, or nullptr
|
||||
*/
|
||||
SK_API sk_sp<SkImage> RasterFromCompressedTextureData(sk_sp<SkData> data,
|
||||
int width,
|
||||
int height,
|
||||
SkTextureCompressionType type);
|
||||
|
||||
/**
|
||||
* Return a SkImage using the encoded data, but attempts to defer decoding until the
|
||||
* image is actually used/drawn. This deferral allows the system to cache the result, either on the
|
||||
* CPU or on the GPU, depending on where the image is drawn. If memory is low, the cache may
|
||||
* be purged, causing the next draw of the image to have to re-decode.
|
||||
*
|
||||
* If alphaType is nullopt, the image's alpha type will be chosen automatically based on the
|
||||
* image format. Transparent images will default to kPremul_SkAlphaType. If alphaType contains
|
||||
* kPremul_SkAlphaType or kUnpremul_SkAlphaType, that alpha type will be used. Forcing opaque
|
||||
* (passing kOpaque_SkAlphaType) is not allowed, and will return nullptr.
|
||||
*
|
||||
* If the encoded format is not supported, nullptr is returned.
|
||||
*
|
||||
* If possible, clients should use SkCodecs::DeferredImage instead.
|
||||
*
|
||||
* @param encoded the encoded data
|
||||
* @return created SkImage, or nullptr
|
||||
|
||||
example: https://fiddle.skia.org/c/@Image_DeferredFromEncodedData
|
||||
*/
|
||||
SK_API sk_sp<SkImage> DeferredFromEncodedData(sk_sp<const SkData> encoded,
|
||||
std::optional<SkAlphaType> alphaType = std::nullopt);
|
||||
|
||||
/** Creates SkImage from data returned by imageGenerator. The image data will not be created
|
||||
(on either the CPU or GPU) until the image is actually drawn.
|
||||
Generated data is owned by SkImage and may not be shared or accessed.
|
||||
|
||||
SkImage is returned if generator data is valid. Valid data parameters vary by type of data
|
||||
and platform.
|
||||
|
||||
imageGenerator may wrap SkPicture data, codec data, or custom data.
|
||||
|
||||
@param imageGenerator stock or custom routines to retrieve SkImage
|
||||
@return created SkImage, or nullptr
|
||||
*/
|
||||
SK_API sk_sp<SkImage> DeferredFromGenerator(std::unique_ptr<SkImageGenerator> imageGenerator);
|
||||
|
||||
enum class BitDepth {
|
||||
kU8, //!< uses 8-bit unsigned int per color component
|
||||
kF16, //!< uses 16-bit float per color component
|
||||
};
|
||||
|
||||
/** Creates SkImage from picture. Returned SkImage width and height are set by dimensions.
|
||||
SkImage draws picture with matrix and paint, set to bitDepth and colorSpace.
|
||||
|
||||
The Picture data is not turned into an image (CPU or GPU) until it is drawn.
|
||||
|
||||
If matrix is nullptr, draws with identity SkMatrix. If paint is nullptr, draws
|
||||
with default SkPaint. colorSpace may be nullptr.
|
||||
|
||||
@param picture stream of drawing commands
|
||||
@param dimensions width and height
|
||||
@param matrix SkMatrix to rotate, scale, translate, and so on; may be nullptr
|
||||
@param paint SkPaint to apply transparency, filtering, and so on; may be nullptr
|
||||
@param bitDepth 8-bit integer or 16-bit float: per component
|
||||
@param colorSpace range of colors; may be nullptr
|
||||
@param props props to use when rasterizing the picture
|
||||
@return created SkImage, or nullptr
|
||||
*/
|
||||
SK_API sk_sp<SkImage> DeferredFromPicture(sk_sp<SkPicture> picture,
|
||||
const SkISize& dimensions,
|
||||
const SkMatrix* matrix,
|
||||
const SkPaint* paint,
|
||||
BitDepth bitDepth,
|
||||
sk_sp<SkColorSpace> colorSpace,
|
||||
SkSurfaceProps props);
|
||||
SK_API sk_sp<SkImage> DeferredFromPicture(sk_sp<SkPicture> picture,
|
||||
const SkISize& dimensions,
|
||||
const SkMatrix* matrix,
|
||||
const SkPaint* paint,
|
||||
BitDepth bitDepth,
|
||||
sk_sp<SkColorSpace> colorSpace);
|
||||
|
||||
/** Creates a CPU-backed SkImage from pixmap, copying the pixel data.
|
||||
As a result, pixmap pixels may be modified or deleted without affecting SkImage.
|
||||
|
||||
SkImage is returned if SkPixmap is valid. Valid SkPixmap parameters include:
|
||||
dimensions are greater than zero;
|
||||
each dimension fits in 29 bits;
|
||||
SkColorType and SkAlphaType are valid, and SkColorType is not kUnknown_SkColorType;
|
||||
row bytes are large enough to hold one row of pixels;
|
||||
pixel address is not nullptr.
|
||||
|
||||
@param pixmap SkImageInfo, pixel address, and row bytes
|
||||
@return copy of SkPixmap pixels, or nullptr
|
||||
|
||||
example: https://fiddle.skia.org/c/@Image_RasterFromPixmapCopy
|
||||
*/
|
||||
SK_API sk_sp<SkImage> RasterFromPixmapCopy(const SkPixmap& pixmap);
|
||||
|
||||
/** Creates CPU-backed SkImage from pixmap, sharing SkPixmap pixels. Pixels must remain valid and
|
||||
unchanged until rasterReleaseProc is called. rasterReleaseProc is passed
|
||||
releaseContext when SkImage is deleted or no longer refers to pixmap pixels.
|
||||
|
||||
Pass nullptr for rasterReleaseProc to share SkPixmap without requiring a callback
|
||||
when SkImage is released. Pass nullptr for releaseContext if rasterReleaseProc
|
||||
does not require state.
|
||||
|
||||
SkImage is returned if pixmap is valid. Valid SkPixmap parameters include:
|
||||
dimensions are greater than zero;
|
||||
each dimension fits in 29 bits;
|
||||
SkColorType and SkAlphaType are valid, and SkColorType is not kUnknown_SkColorType;
|
||||
row bytes are large enough to hold one row of pixels;
|
||||
pixel address is not nullptr.
|
||||
|
||||
@param pixmap SkImageInfo, pixel address, and row bytes
|
||||
@param rasterReleaseProc function called when pixels can be released; or nullptr
|
||||
@param releaseContext state passed to rasterReleaseProc; or nullptr
|
||||
@return SkImage sharing pixmap
|
||||
*/
|
||||
SK_API sk_sp<SkImage> RasterFromPixmap(const SkPixmap& pixmap,
|
||||
RasterReleaseProc rasterReleaseProc,
|
||||
ReleaseContext releaseContext);
|
||||
|
||||
/** Creates CPU-backed SkImage from pixel data described by info.
|
||||
The pixels data will *not* be copied.
|
||||
|
||||
SkImage is returned if SkImageInfo is valid. Valid SkImageInfo parameters include:
|
||||
dimensions are greater than zero;
|
||||
each dimension fits in 29 bits;
|
||||
SkColorType and SkAlphaType are valid, and SkColorType is not kUnknown_SkColorType;
|
||||
rowBytes are large enough to hold one row of pixels;
|
||||
pixels is not nullptr, and contains enough data for SkImage.
|
||||
|
||||
@param info contains width, height, SkAlphaType, SkColorType, SkColorSpace
|
||||
@param pixels address or pixel storage
|
||||
@param rowBytes size of pixel row or larger
|
||||
@return SkImage sharing pixels, or nullptr
|
||||
*/
|
||||
SK_API sk_sp<SkImage> RasterFromData(const SkImageInfo& info,
|
||||
sk_sp<SkData> pixels,
|
||||
size_t rowBytes);
|
||||
|
||||
/** Creates a filtered SkImage on the CPU. filter processes the src image, potentially changing
|
||||
the color, position, and size. subset is the bounds of src that are processed
|
||||
by filter. clipBounds is the expected bounds of the filtered SkImage. outSubset
|
||||
is required storage for the actual bounds of the filtered SkImage. offset is
|
||||
required storage for translation of returned SkImage.
|
||||
|
||||
Returns nullptr a filtered result could not be created. If nullptr is returned, outSubset
|
||||
and offset are undefined.
|
||||
|
||||
Useful for animation of SkImageFilter that varies size from frame to frame.
|
||||
outSubset describes the valid bounds of returned image. offset translates the returned SkImage
|
||||
to keep subsequent animation frames aligned with respect to each other.
|
||||
|
||||
@param src the image to be filtered
|
||||
@param filter the image filter to be applied
|
||||
@param subset bounds of SkImage processed by filter
|
||||
@param clipBounds expected bounds of filtered SkImage
|
||||
@param outSubset storage for returned SkImage bounds
|
||||
@param offset storage for returned SkImage translation
|
||||
@return filtered SkImage, or nullptr
|
||||
*/
|
||||
SK_API sk_sp<SkImage> MakeWithFilter(sk_sp<SkImage> src,
|
||||
const SkImageFilter* filter,
|
||||
const SkIRect& subset,
|
||||
const SkIRect& clipBounds,
|
||||
SkIRect* outSubset,
|
||||
SkIPoint* offset);
|
||||
|
||||
} // namespace SkImages
|
||||
|
||||
/** \class SkImage
|
||||
SkImage describes a two dimensional array of pixels to draw. The pixels may be
|
||||
decoded in a raster bitmap, encoded in a SkPicture or compressed data stream,
|
||||
or located in GPU memory as a GPU texture.
|
||||
|
||||
SkImage cannot be modified after it is created. SkImage may allocate additional
|
||||
storage as needed; for instance, an encoded SkImage may decode when drawn.
|
||||
|
||||
SkImage width and height are greater than zero. Creating an SkImage with zero width
|
||||
or height returns SkImage equal to nullptr.
|
||||
|
||||
SkImage may be created from SkBitmap, SkPixmap, SkSurface, SkPicture, encoded streams,
|
||||
GPU texture, YUV_ColorSpace data, or hardware buffer. Encoded streams supported
|
||||
include BMP, GIF, HEIF, ICO, JPEG, PNG, WBMP, WebP. Supported encoding details
|
||||
vary with platform.
|
||||
|
||||
See SkImages namespace for the static factory methods to make SkImages.
|
||||
|
||||
Clients should *not* subclass SkImage as there is a lot of internal machinery that is
|
||||
not publicly accessible.
|
||||
*/
|
||||
class SK_API SkImage : public SkRefCnt {
|
||||
public:
|
||||
/** Returns a SkImageInfo describing the width, height, color type, alpha type, and color space
|
||||
of the SkImage.
|
||||
|
||||
@return image info of SkImage.
|
||||
*/
|
||||
const SkImageInfo& imageInfo() const { return fInfo; }
|
||||
|
||||
/** Returns pixel count in each row.
|
||||
|
||||
@return pixel width in SkImage
|
||||
*/
|
||||
int width() const { return fInfo.width(); }
|
||||
|
||||
/** Returns pixel row count.
|
||||
|
||||
@return pixel height in SkImage
|
||||
*/
|
||||
int height() const { return fInfo.height(); }
|
||||
|
||||
/** Returns SkISize { width(), height() }.
|
||||
|
||||
@return integral size of width() and height()
|
||||
*/
|
||||
SkISize dimensions() const { return SkISize::Make(fInfo.width(), fInfo.height()); }
|
||||
|
||||
/** Returns SkIRect { 0, 0, width(), height() }.
|
||||
|
||||
@return integral rectangle from origin to width() and height()
|
||||
*/
|
||||
SkIRect bounds() const { return SkIRect::MakeWH(fInfo.width(), fInfo.height()); }
|
||||
|
||||
/** Returns value unique to image. SkImage contents cannot change after SkImage is
|
||||
created. Any operation to create a new SkImage will receive generate a new
|
||||
unique number.
|
||||
|
||||
@return unique identifier
|
||||
*/
|
||||
uint32_t uniqueID() const { return fUniqueID; }
|
||||
|
||||
/** Returns SkAlphaType.
|
||||
|
||||
SkAlphaType returned was a parameter to an SkImage constructor,
|
||||
or was parsed from encoded data.
|
||||
|
||||
@return SkAlphaType in SkImage
|
||||
|
||||
example: https://fiddle.skia.org/c/@Image_alphaType
|
||||
*/
|
||||
SkAlphaType alphaType() const;
|
||||
|
||||
/** Returns SkColorType if known; otherwise, returns kUnknown_SkColorType.
|
||||
|
||||
@return SkColorType of SkImage
|
||||
|
||||
example: https://fiddle.skia.org/c/@Image_colorType
|
||||
*/
|
||||
SkColorType colorType() const;
|
||||
|
||||
/** Returns SkColorSpace, the range of colors, associated with SkImage. The
|
||||
reference count of SkColorSpace is unchanged. The returned SkColorSpace is
|
||||
immutable.
|
||||
|
||||
SkColorSpace returned was passed to an SkImage constructor,
|
||||
or was parsed from encoded data. SkColorSpace returned may be ignored when SkImage
|
||||
is drawn, depending on the capabilities of the SkSurface receiving the drawing.
|
||||
|
||||
@return SkColorSpace in SkImage, or nullptr
|
||||
|
||||
example: https://fiddle.skia.org/c/@Image_colorSpace
|
||||
*/
|
||||
SkColorSpace* colorSpace() const;
|
||||
|
||||
/** Returns a smart pointer to SkColorSpace, the range of colors, associated with
|
||||
SkImage. The smart pointer tracks the number of objects sharing this
|
||||
SkColorSpace reference so the memory is released when the owners destruct.
|
||||
|
||||
The returned SkColorSpace is immutable.
|
||||
|
||||
SkColorSpace returned was passed to an SkImage constructor,
|
||||
or was parsed from encoded data. SkColorSpace returned may be ignored when SkImage
|
||||
is drawn, depending on the capabilities of the SkSurface receiving the drawing.
|
||||
|
||||
@return SkColorSpace in SkImage, or nullptr, wrapped in a smart pointer
|
||||
|
||||
example: https://fiddle.skia.org/c/@Image_refColorSpace
|
||||
*/
|
||||
sk_sp<SkColorSpace> refColorSpace() const;
|
||||
|
||||
/** Returns true if SkImage pixels represent transparency only. If true, each pixel
|
||||
is packed in 8 bits as defined by kAlpha_8_SkColorType.
|
||||
|
||||
@return true if pixels represent a transparency mask
|
||||
|
||||
example: https://fiddle.skia.org/c/@Image_isAlphaOnly
|
||||
*/
|
||||
bool isAlphaOnly() const;
|
||||
|
||||
/** Returns true if pixels ignore their alpha value and are treated as fully opaque.
|
||||
|
||||
@return true if SkAlphaType is kOpaque_SkAlphaType
|
||||
*/
|
||||
bool isOpaque() const { return SkAlphaTypeIsOpaque(this->alphaType()); }
|
||||
|
||||
/**
|
||||
* Make a shader with the specified tiling and mipmap sampling.
|
||||
*/
|
||||
sk_sp<SkShader> makeShader(SkTileMode tmx, SkTileMode tmy, const SkSamplingOptions&,
|
||||
const SkMatrix* localMatrix = nullptr) const;
|
||||
sk_sp<SkShader> makeShader(SkTileMode tmx, SkTileMode tmy, const SkSamplingOptions& sampling,
|
||||
const SkMatrix& lm) const;
|
||||
/** Defaults to clamp in both X and Y. */
|
||||
sk_sp<SkShader> makeShader(const SkSamplingOptions& sampling, const SkMatrix& lm) const;
|
||||
sk_sp<SkShader> makeShader(const SkSamplingOptions& sampling,
|
||||
const SkMatrix* lm = nullptr) const;
|
||||
|
||||
/**
|
||||
* makeRawShader functions like makeShader, but for images that contain non-color data.
|
||||
* This includes images encoding things like normals, material properties (eg, roughness),
|
||||
* heightmaps, or any other purely mathematical data that happens to be stored in an image.
|
||||
* These types of images are useful with some programmable shaders (see: SkRuntimeEffect).
|
||||
*
|
||||
* Raw image shaders work like regular image shaders (including filtering and tiling), with
|
||||
* a few major differences:
|
||||
* - No color space transformation is ever applied (the color space of the image is ignored).
|
||||
* - Images with an alpha type of kUnpremul are *not* automatically premultiplied.
|
||||
* - Bicubic filtering is not supported. If SkSamplingOptions::useCubic is true, these
|
||||
* factories will return nullptr.
|
||||
*/
|
||||
sk_sp<SkShader> makeRawShader(SkTileMode tmx, SkTileMode tmy, const SkSamplingOptions&,
|
||||
const SkMatrix* localMatrix = nullptr) const;
|
||||
sk_sp<SkShader> makeRawShader(SkTileMode tmx, SkTileMode tmy, const SkSamplingOptions& sampling,
|
||||
const SkMatrix& lm) const;
|
||||
/** Defaults to clamp in both X and Y. */
|
||||
sk_sp<SkShader> makeRawShader(const SkSamplingOptions& sampling, const SkMatrix& lm) const;
|
||||
sk_sp<SkShader> makeRawShader(const SkSamplingOptions& sampling,
|
||||
const SkMatrix* lm = nullptr) const;
|
||||
|
||||
/** Copies SkImage pixel address, row bytes, and SkImageInfo to pixmap, if address
|
||||
is available, and returns true. If pixel address is not available, return
|
||||
false and leave pixmap unchanged.
|
||||
|
||||
@param pixmap storage for pixel state if pixels are readable; otherwise, ignored
|
||||
@return true if SkImage has direct access to pixels
|
||||
|
||||
example: https://fiddle.skia.org/c/@Image_peekPixels
|
||||
*/
|
||||
bool peekPixels(SkPixmap* pixmap) const;
|
||||
|
||||
/** Returns true if the contents of SkImage was created on or uploaded to GPU memory,
|
||||
and is available as a GPU texture.
|
||||
|
||||
@return true if SkImage is a GPU texture
|
||||
|
||||
example: https://fiddle.skia.org/c/@Image_isTextureBacked
|
||||
*/
|
||||
virtual bool isTextureBacked() const = 0;
|
||||
|
||||
/** Returns an approximation of the amount of texture memory used by the image. Returns
|
||||
zero if the image is not texture backed or if the texture has an external format.
|
||||
*/
|
||||
virtual size_t textureSize() const = 0;
|
||||
|
||||
/** Returns true if SkImage can be drawn on either raster surface or GPU surface.
|
||||
If recorder is nullptr, tests if SkImage draws on raster surface;
|
||||
otherwise, tests if SkImage draws on the associated GPU surface.
|
||||
|
||||
SkImage backed by GPU texture may become invalid if associated context is
|
||||
invalid. lazy image may be invalid and may not draw to raster surface or
|
||||
GPU surface or both.
|
||||
|
||||
@param context GPU context
|
||||
@return true if SkImage can be drawn
|
||||
|
||||
example: https://fiddle.skia.org/c/@Image_isValid
|
||||
*/
|
||||
virtual bool isValid(SkRecorder*) const = 0;
|
||||
|
||||
/** \enum SkImage::CachingHint
|
||||
CachingHint selects whether Skia may internally cache SkBitmap generated by
|
||||
decoding SkImage, or by copying SkImage from GPU to CPU. The default behavior
|
||||
allows caching SkBitmap.
|
||||
|
||||
Choose kDisallow_CachingHint if SkImage pixels are to be used only once, or
|
||||
if SkImage pixels reside in a cache outside of Skia, or to reduce memory pressure.
|
||||
|
||||
Choosing kAllow_CachingHint does not ensure that pixels will be cached.
|
||||
SkImage pixels may not be cached if memory requirements are too large or
|
||||
pixels are not accessible.
|
||||
*/
|
||||
enum CachingHint {
|
||||
kAllow_CachingHint, //!< allows internally caching decoded and copied pixels
|
||||
kDisallow_CachingHint, //!< disallows internally caching decoded and copied pixels
|
||||
};
|
||||
|
||||
/** Copies SkRect of pixels from SkImage to dstPixels. Copy starts at offset (srcX, srcY),
|
||||
and does not exceed SkImage (width(), height()).
|
||||
|
||||
Graphite has deprecated this API in favor of the equivalent asynchronous API on
|
||||
skgpu::graphite::Context (with an optional explicit synchonization).
|
||||
|
||||
dstInfo specifies width, height, SkColorType, SkAlphaType, and SkColorSpace of
|
||||
destination. dstRowBytes specifies the gap from one destination row to the next.
|
||||
Returns true if pixels are copied. Returns false if:
|
||||
- dstInfo.addr() equals nullptr
|
||||
- dstRowBytes is less than dstInfo.minRowBytes()
|
||||
- SkPixelRef is nullptr
|
||||
|
||||
Pixels are copied only if pixel conversion is possible. If SkImage SkColorType is
|
||||
kGray_8_SkColorType, or kAlpha_8_SkColorType; dstInfo.colorType() must match.
|
||||
If SkImage SkColorType is kGray_8_SkColorType, dstInfo.colorSpace() must match.
|
||||
If SkImage SkAlphaType is kOpaque_SkAlphaType, dstInfo.alphaType() must
|
||||
match. If SkImage SkColorSpace is nullptr, dstInfo.colorSpace() must match. Returns
|
||||
false if pixel conversion is not possible.
|
||||
|
||||
srcX and srcY may be negative to copy only top or left of source. Returns
|
||||
false if width() or height() is zero or negative.
|
||||
Returns false if abs(srcX) >= Image width(), or if abs(srcY) >= Image height().
|
||||
|
||||
If cachingHint is kAllow_CachingHint, pixels may be retained locally.
|
||||
If cachingHint is kDisallow_CachingHint, pixels are not added to the local cache.
|
||||
|
||||
@param context the GrDirectContext in play, if it exists
|
||||
@param dstInfo destination width, height, SkColorType, SkAlphaType, SkColorSpace
|
||||
@param dstPixels destination pixel storage
|
||||
@param dstRowBytes destination row length
|
||||
@param srcX column index whose absolute value is less than width()
|
||||
@param srcY row index whose absolute value is less than height()
|
||||
@param cachingHint whether the pixels should be cached locally
|
||||
@return true if pixels are copied to dstPixels
|
||||
*/
|
||||
bool readPixels(GrDirectContext* context,
|
||||
const SkImageInfo& dstInfo,
|
||||
void* dstPixels,
|
||||
size_t dstRowBytes,
|
||||
int srcX, int srcY,
|
||||
CachingHint cachingHint = kAllow_CachingHint) const;
|
||||
|
||||
/** Copies a SkRect of pixels from SkImage to dst. Copy starts at (srcX, srcY), and
|
||||
does not exceed SkImage (width(), height()).
|
||||
|
||||
Graphite has deprecated this API in favor of the equivalent asynchronous API on
|
||||
skgpu::graphite::Context (with an optional explicit synchonization).
|
||||
|
||||
dst specifies width, height, SkColorType, SkAlphaType, SkColorSpace, pixel storage,
|
||||
and row bytes of destination. dst.rowBytes() specifics the gap from one destination
|
||||
row to the next. Returns true if pixels are copied. Returns false if:
|
||||
- dst pixel storage equals nullptr
|
||||
- dst.rowBytes is less than SkImageInfo::minRowBytes
|
||||
- SkPixelRef is nullptr
|
||||
|
||||
Pixels are copied only if pixel conversion is possible. If SkImage SkColorType is
|
||||
kGray_8_SkColorType, or kAlpha_8_SkColorType; dst.colorType() must match.
|
||||
If SkImage SkColorType is kGray_8_SkColorType, dst.colorSpace() must match.
|
||||
If SkImage SkAlphaType is kOpaque_SkAlphaType, dst.alphaType() must
|
||||
match. If SkImage SkColorSpace is nullptr, dst.colorSpace() must match. Returns
|
||||
false if pixel conversion is not possible.
|
||||
|
||||
srcX and srcY may be negative to copy only top or left of source. Returns
|
||||
false if width() or height() is zero or negative.
|
||||
Returns false if abs(srcX) >= Image width(), or if abs(srcY) >= Image height().
|
||||
|
||||
If cachingHint is kAllow_CachingHint, pixels may be retained locally.
|
||||
If cachingHint is kDisallow_CachingHint, pixels are not added to the local cache.
|
||||
|
||||
@param context the GrDirectContext in play, if it exists
|
||||
@param dst destination SkPixmap: SkImageInfo, pixels, row bytes
|
||||
@param srcX column index whose absolute value is less than width()
|
||||
@param srcY row index whose absolute value is less than height()
|
||||
@param cachingHint whether the pixels should be cached locallyZ
|
||||
@return true if pixels are copied to dst
|
||||
*/
|
||||
bool readPixels(GrDirectContext* context,
|
||||
const SkPixmap& dst,
|
||||
int srcX,
|
||||
int srcY,
|
||||
CachingHint cachingHint = kAllow_CachingHint) const;
|
||||
|
||||
#ifndef SK_IMAGE_READ_PIXELS_DISABLE_LEGACY_API
|
||||
/** Deprecated. Use the variants that accept a GrDirectContext. */
|
||||
bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
|
||||
int srcX, int srcY, CachingHint cachingHint = kAllow_CachingHint) const;
|
||||
bool readPixels(const SkPixmap& dst, int srcX, int srcY,
|
||||
CachingHint cachingHint = kAllow_CachingHint) const;
|
||||
#endif
|
||||
|
||||
/** The result from asyncRescaleAndReadPixels() or asyncRescaleAndReadPixelsYUV420(). */
|
||||
class AsyncReadResult {
|
||||
public:
|
||||
AsyncReadResult(const AsyncReadResult&) = delete;
|
||||
AsyncReadResult(AsyncReadResult&&) = delete;
|
||||
AsyncReadResult& operator=(const AsyncReadResult&) = delete;
|
||||
AsyncReadResult& operator=(AsyncReadResult&&) = delete;
|
||||
|
||||
virtual ~AsyncReadResult() = default;
|
||||
/** Returns how many planes of data are in the result. e.g. 3 for YUV data. */
|
||||
virtual int count() const = 0;
|
||||
/** Returns the raw pixel data for a given plane.
|
||||
*
|
||||
* It will be organized as per the dst SkImageInfo passed in to the async read call.
|
||||
*
|
||||
* Clients may wish to create an SkPixmap with this data using the dst SkImageInfo
|
||||
* and rowBytes(i).
|
||||
*/
|
||||
virtual const void* data(int i) const = 0;
|
||||
/** Returns how many bytes correspond to a single row of image data */
|
||||
virtual size_t rowBytes(int i) const = 0;
|
||||
|
||||
protected:
|
||||
AsyncReadResult() = default;
|
||||
};
|
||||
|
||||
/** Client-provided context that is passed to client-provided ReadPixelsContext. */
|
||||
using ReadPixelsContext = void*;
|
||||
|
||||
/** Client-provided callback to asyncRescaleAndReadPixels() or
|
||||
asyncRescaleAndReadPixelsYUV420() that is called when read result is ready or on failure.
|
||||
*/
|
||||
using ReadPixelsCallback = void(ReadPixelsContext, std::unique_ptr<const AsyncReadResult>);
|
||||
|
||||
enum class RescaleGamma : bool { kSrc, kLinear };
|
||||
|
||||
enum class RescaleMode {
|
||||
kNearest,
|
||||
kLinear,
|
||||
kRepeatedLinear,
|
||||
kRepeatedCubic,
|
||||
};
|
||||
|
||||
/** Makes image pixel data available to caller, possibly asynchronously. It can also rescale
|
||||
the image pixels.
|
||||
|
||||
Currently asynchronous reads are only supported in the Ganesh GPU backend and only when the
|
||||
underlying 3D API supports transfer buffers and CPU/GPU synchronization primitives. In all
|
||||
other cases this operates synchronously.
|
||||
|
||||
For the Graphite backend this API has been deprecated in favor of the equivalent API
|
||||
on skgpu::graphite::Context.
|
||||
|
||||
Data is read from the source sub-rectangle, is optionally converted to a linear gamma, is
|
||||
rescaled to the size indicated by 'info', is then converted to the color space, color type,
|
||||
and alpha type of 'info'. A 'srcRect' that is not contained by the bounds of the image
|
||||
causes failure.
|
||||
|
||||
When the pixel data is ready the caller's ReadPixelsCallback is called with a
|
||||
AsyncReadResult containing pixel data in the requested color type, alpha type, and color
|
||||
space. The AsyncReadResult will have count() == 1. Upon failure the callback is called with
|
||||
nullptr for AsyncReadResult. For a GPU image this flushes work but a submit must occur to
|
||||
guarantee a finite time before the callback is called.
|
||||
|
||||
The data is valid for the lifetime of AsyncReadResult with the exception that if the SkImage
|
||||
is GPU-backed the data is immediately invalidated if the context is abandoned or
|
||||
destroyed.
|
||||
|
||||
@param info info of the requested pixels
|
||||
@param srcRect subrectangle of image to read
|
||||
@param rescaleGamma controls whether rescaling is done in the image's gamma or whether
|
||||
the source data is transformed to a linear gamma before rescaling.
|
||||
@param rescaleMode controls the technique (and cost) of the rescaling
|
||||
@param callback function to call with result of the read
|
||||
@param context passed to callback
|
||||
*/
|
||||
void asyncRescaleAndReadPixels(const SkImageInfo& info,
|
||||
const SkIRect& srcRect,
|
||||
RescaleGamma rescaleGamma,
|
||||
RescaleMode rescaleMode,
|
||||
ReadPixelsCallback callback,
|
||||
ReadPixelsContext context) const;
|
||||
|
||||
/**
|
||||
Similar to asyncRescaleAndReadPixels but performs an additional conversion to YUV. The
|
||||
RGB->YUV conversion is controlled by 'yuvColorSpace'. The YUV data is returned as three
|
||||
planes ordered y, u, v. The u and v planes are half the width and height of the resized
|
||||
rectangle. The y, u, and v values are single bytes. Currently this fails if 'dstSize'
|
||||
width and height are not even. A 'srcRect' that is not contained by the bounds of the
|
||||
image causes failure.
|
||||
|
||||
When the pixel data is ready the caller's ReadPixelsCallback is called with a
|
||||
AsyncReadResult containing the planar data. The AsyncReadResult will have count() == 3.
|
||||
Upon failure the callback is called with nullptr for AsyncReadResult. For a GPU image this
|
||||
flushes work but a submit must occur to guarantee a finite time before the callback is
|
||||
called.
|
||||
|
||||
The data is valid for the lifetime of AsyncReadResult with the exception that if the SkImage
|
||||
is GPU-backed the data is immediately invalidated if the context is abandoned or
|
||||
destroyed.
|
||||
|
||||
@param yuvColorSpace The transformation from RGB to YUV. Applied to the resized image
|
||||
after it is converted to dstColorSpace.
|
||||
@param dstColorSpace The color space to convert the resized image to, after rescaling.
|
||||
@param srcRect The portion of the image to rescale and convert to YUV planes.
|
||||
@param dstSize The size to rescale srcRect to
|
||||
@param rescaleGamma controls whether rescaling is done in the image's gamma or whether
|
||||
the source data is transformed to a linear gamma before rescaling.
|
||||
@param rescaleMode controls the technique (and cost) of the rescaling
|
||||
@param callback function to call with the planar read result
|
||||
@param context passed to callback
|
||||
*/
|
||||
void asyncRescaleAndReadPixelsYUV420(SkYUVColorSpace yuvColorSpace,
|
||||
sk_sp<SkColorSpace> dstColorSpace,
|
||||
const SkIRect& srcRect,
|
||||
const SkISize& dstSize,
|
||||
RescaleGamma rescaleGamma,
|
||||
RescaleMode rescaleMode,
|
||||
ReadPixelsCallback callback,
|
||||
ReadPixelsContext context) const;
|
||||
|
||||
/**
|
||||
* Identical to asyncRescaleAndReadPixelsYUV420 but a fourth plane is returned in the
|
||||
* AsyncReadResult passed to 'callback'. The fourth plane contains the alpha chanel at the
|
||||
* same full resolution as the Y plane.
|
||||
*/
|
||||
void asyncRescaleAndReadPixelsYUVA420(SkYUVColorSpace yuvColorSpace,
|
||||
sk_sp<SkColorSpace> dstColorSpace,
|
||||
const SkIRect& srcRect,
|
||||
const SkISize& dstSize,
|
||||
RescaleGamma rescaleGamma,
|
||||
RescaleMode rescaleMode,
|
||||
ReadPixelsCallback callback,
|
||||
ReadPixelsContext context) const;
|
||||
|
||||
/** Copies SkImage to dst, scaling pixels to fit dst.width() and dst.height(), and
|
||||
converting pixels to match dst.colorType() and dst.alphaType(). Returns true if
|
||||
pixels are copied. Returns false if dst.addr() is nullptr, or dst.rowBytes() is
|
||||
less than dst SkImageInfo::minRowBytes.
|
||||
|
||||
Pixels are copied only if pixel conversion is possible. If SkImage SkColorType is
|
||||
kGray_8_SkColorType, or kAlpha_8_SkColorType; dst.colorType() must match.
|
||||
If SkImage SkColorType is kGray_8_SkColorType, dst.colorSpace() must match.
|
||||
If SkImage SkAlphaType is kOpaque_SkAlphaType, dst.alphaType() must
|
||||
match. If SkImage SkColorSpace is nullptr, dst.colorSpace() must match. Returns
|
||||
false if pixel conversion is not possible.
|
||||
|
||||
If cachingHint is kAllow_CachingHint, pixels may be retained locally.
|
||||
If cachingHint is kDisallow_CachingHint, pixels are not added to the local cache.
|
||||
|
||||
@param dst destination SkPixmap: SkImageInfo, pixels, row bytes
|
||||
@return true if pixels are scaled to fit dst
|
||||
*/
|
||||
bool scalePixels(const SkPixmap& dst, const SkSamplingOptions&,
|
||||
CachingHint cachingHint = kAllow_CachingHint) const;
|
||||
|
||||
/**
|
||||
* Create a new image by copying this image and scaling to fit the ImageInfo's dimensions
|
||||
* and converting the pixels into the ImageInfo's ColorInfo.
|
||||
* This is done retaining the domain (backend) of the image (e.g. gpu, raster)
|
||||
*
|
||||
* The Recorder parameter is required if the original image was created on a graphite Recorder,
|
||||
* but must be nullptr if it was create in some other way (e.g. GrContext, raster, deferred).
|
||||
*
|
||||
* return nullptr if the requested ColorInfo is not supported, its dimesions are out of range,
|
||||
* or if the recorder is null on a graphite Image.
|
||||
*/
|
||||
sk_sp<SkImage> makeScaled(SkRecorder*, const SkImageInfo&, const SkSamplingOptions&) const;
|
||||
sk_sp<SkImage> makeScaled(SkRecorder*,
|
||||
const SkImageInfo&,
|
||||
const SkSamplingOptions&,
|
||||
const SkSurfaceProps&) const;
|
||||
|
||||
sk_sp<SkImage> makeScaled(const SkImageInfo& info, const SkSamplingOptions& sampling) const;
|
||||
|
||||
/** Returns encoded SkImage pixels as SkData, if SkImage was created from supported
|
||||
encoded stream format. Platform support for formats vary and may require building
|
||||
with one or more of: SK_ENCODE_JPEG, SK_ENCODE_PNG, SK_ENCODE_WEBP.
|
||||
|
||||
Returns nullptr if SkImage contents are not encoded.
|
||||
|
||||
@return encoded SkImage, or nullptr
|
||||
|
||||
example: https://fiddle.skia.org/c/@Image_refEncodedData
|
||||
*/
|
||||
sk_sp<const SkData> refEncodedData() const;
|
||||
|
||||
struct RequiredProperties {
|
||||
bool fMipmapped = false;
|
||||
|
||||
bool operator==(const RequiredProperties& other) const {
|
||||
return fMipmapped == other.fMipmapped;
|
||||
}
|
||||
|
||||
bool operator!=(const RequiredProperties& other) const { return !(*this == other); }
|
||||
|
||||
bool operator<(const RequiredProperties& other) const {
|
||||
return fMipmapped < other.fMipmapped;
|
||||
}
|
||||
};
|
||||
|
||||
/** Returns subset of this image.
|
||||
|
||||
Returns nullptr if any of the following are true:
|
||||
- Subset is empty
|
||||
- Subset is not contained inside the image's bounds
|
||||
- Pixels in the image could not be read or copied
|
||||
- This image is texture-backed and the provided context is null or does not match
|
||||
the source image's context.
|
||||
|
||||
If the source image was texture-backed, the resulting image will be texture-backed also.
|
||||
Otherwise, the returned image will be raster-backed.
|
||||
|
||||
@param recorder the recorder of the source image (nullptr is ok if the
|
||||
source image was texture-backed).
|
||||
@param subset bounds of returned SkImage
|
||||
@param RequiredProperties properties the returned SkImage must possess (e.g. mipmaps)
|
||||
@return the subsetted image, or nullptr
|
||||
*/
|
||||
virtual sk_sp<SkImage> makeSubset(SkRecorder*,
|
||||
const SkIRect& subset,
|
||||
RequiredProperties) const = 0;
|
||||
|
||||
/**
|
||||
* Returns true if the image has mipmap levels.
|
||||
*/
|
||||
bool hasMipmaps() const;
|
||||
|
||||
/**
|
||||
* Returns true if the image holds protected content.
|
||||
*/
|
||||
bool isProtected() const;
|
||||
|
||||
/**
|
||||
* Returns an image with the same "base" pixels as the this image, but with mipmap levels
|
||||
* automatically generated and attached.
|
||||
*/
|
||||
sk_sp<SkImage> withDefaultMipmaps() const;
|
||||
|
||||
/** Returns raster image or lazy image. Copies SkImage backed by GPU texture into
|
||||
CPU memory if needed. Returns original SkImage if decoded in raster bitmap,
|
||||
or if encoded in a stream.
|
||||
|
||||
Returns nullptr if backed by GPU texture and copy fails.
|
||||
|
||||
@return raster image, lazy image, or nullptr
|
||||
|
||||
example: https://fiddle.skia.org/c/@Image_makeNonTextureImage
|
||||
*/
|
||||
sk_sp<SkImage> makeNonTextureImage(GrDirectContext* = nullptr) const;
|
||||
|
||||
/** Returns raster image. Copies SkImage backed by GPU texture into CPU memory,
|
||||
or decodes SkImage from lazy image. Returns original SkImage if decoded in
|
||||
raster bitmap.
|
||||
|
||||
Returns nullptr if copy, decode, or pixel read fails.
|
||||
|
||||
If cachingHint is kAllow_CachingHint, pixels may be retained locally.
|
||||
If cachingHint is kDisallow_CachingHint, pixels are not added to the local cache.
|
||||
|
||||
@return raster image, or nullptr
|
||||
|
||||
example: https://fiddle.skia.org/c/@Image_makeRasterImage
|
||||
*/
|
||||
sk_sp<SkImage> makeRasterImage(GrDirectContext*,
|
||||
CachingHint cachingHint = kDisallow_CachingHint) const;
|
||||
|
||||
#if !defined(SK_IMAGE_READ_PIXELS_DISABLE_LEGACY_API)
|
||||
sk_sp<SkImage> makeRasterImage(CachingHint cachingHint = kDisallow_CachingHint) const {
|
||||
return this->makeRasterImage(nullptr, cachingHint);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Deprecated.
|
||||
*/
|
||||
enum LegacyBitmapMode {
|
||||
kRO_LegacyBitmapMode, //!< returned bitmap is read-only and immutable
|
||||
};
|
||||
|
||||
/** Deprecated.
|
||||
Creates raster SkBitmap with same pixels as SkImage. If legacyBitmapMode is
|
||||
kRO_LegacyBitmapMode, returned bitmap is read-only and immutable.
|
||||
Returns true if SkBitmap is stored in bitmap. Returns false and resets bitmap if
|
||||
SkBitmap write did not succeed.
|
||||
|
||||
@param bitmap storage for legacy SkBitmap
|
||||
@param legacyBitmapMode bitmap is read-only and immutable
|
||||
@return true if SkBitmap was created
|
||||
*/
|
||||
bool asLegacyBitmap(SkBitmap* bitmap,
|
||||
LegacyBitmapMode legacyBitmapMode = kRO_LegacyBitmapMode) const;
|
||||
|
||||
/** Returns true if SkImage is backed by an image-generator or other service that creates
|
||||
and caches its pixels or texture on-demand.
|
||||
|
||||
@return true if SkImage is created as needed
|
||||
|
||||
example: https://fiddle.skia.org/c/@Image_isLazyGenerated_a
|
||||
example: https://fiddle.skia.org/c/@Image_isLazyGenerated_b
|
||||
*/
|
||||
virtual bool isLazyGenerated() const = 0;
|
||||
|
||||
/** Creates SkImage in target SkColorSpace.
|
||||
Returns nullptr if SkImage could not be created.
|
||||
|
||||
Returns original SkImage if it is in target SkColorSpace.
|
||||
Otherwise, converts pixels from SkImage SkColorSpace to target SkColorSpace.
|
||||
If SkImage colorSpace() returns nullptr, SkImage SkColorSpace is assumed to be sRGB.
|
||||
|
||||
If this image is graphite-backed, the recorder parameter is required.
|
||||
|
||||
@param targetColorSpace SkColorSpace describing color range of returned SkImage
|
||||
@param recorder The Recorder in which to create the new image
|
||||
@param RequiredProperties properties the returned SkImage must possess (e.g. mipmaps)
|
||||
@return created SkImage in target SkColorSpace
|
||||
*/
|
||||
virtual sk_sp<SkImage> makeColorSpace(SkRecorder*,
|
||||
sk_sp<SkColorSpace> targetColorSpace,
|
||||
RequiredProperties) const = 0;
|
||||
|
||||
/** Experimental.
|
||||
Creates SkImage in target SkColorType and SkColorSpace.
|
||||
Returns nullptr if SkImage could not be created.
|
||||
|
||||
Returns original SkImage if it is in target SkColorType and SkColorSpace.
|
||||
|
||||
If this image is graphite-backed, the recorder parameter is required.
|
||||
|
||||
@param targetColorType SkColorType of returned SkImage
|
||||
@param targetColorSpace SkColorSpace of returned SkImage
|
||||
@param recorder The Recorder in which to create the new image
|
||||
@param RequiredProperties properties the returned SkImage must possess (e.g. mipmaps)
|
||||
@return created SkImage in target SkColorType and SkColorSpace
|
||||
*/
|
||||
virtual sk_sp<SkImage> makeColorTypeAndColorSpace(SkRecorder*,
|
||||
SkColorType targetColorType,
|
||||
sk_sp<SkColorSpace> targetColorSpace,
|
||||
RequiredProperties) const = 0;
|
||||
|
||||
/** Creates a new SkImage identical to this one, but with a different SkColorSpace.
|
||||
This does not convert the underlying pixel data, so the resulting image will draw
|
||||
differently.
|
||||
*/
|
||||
sk_sp<SkImage> reinterpretColorSpace(sk_sp<SkColorSpace> newColorSpace) const;
|
||||
|
||||
private:
|
||||
SkImage(const SkImageInfo& info, uint32_t uniqueID);
|
||||
|
||||
friend class SkBitmap;
|
||||
friend class SkImage_Base; // for private ctor
|
||||
friend class SkImage_Raster; // for withMipmaps
|
||||
friend class SkMipmapBuilder;
|
||||
|
||||
SkImageInfo fInfo;
|
||||
const uint32_t fUniqueID;
|
||||
|
||||
sk_sp<SkImage> withMipmaps(sk_sp<SkMipmap>) const;
|
||||
|
||||
using INHERITED = SkRefCnt;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* 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 SkImageFilter_DEFINED
|
||||
#define SkImageFilter_DEFINED
|
||||
|
||||
#include "include/core/SkFlattenable.h"
|
||||
#include "include/core/SkRect.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/private/base/SkAPI.h"
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
class SkColorFilter;
|
||||
class SkMatrix;
|
||||
struct SkDeserialProcs;
|
||||
|
||||
/**
|
||||
* Base class for image filters. If one is installed in the paint, then all drawing occurs as
|
||||
* usual, but it is as if the drawing happened into an offscreen (before the xfermode is applied).
|
||||
* This offscreen bitmap will then be handed to the imagefilter, who in turn creates a new bitmap
|
||||
* which is what will finally be drawn to the device (using the original xfermode).
|
||||
*
|
||||
* The local space of image filters matches the local space of the drawn geometry. For instance if
|
||||
* there is rotation on the canvas, the blur will be computed along those rotated axes and not in
|
||||
* the device space. In order to achieve this result, the actual drawing of the geometry may happen
|
||||
* in an unrotated coordinate system so that the filtered image can be computed more easily, and
|
||||
* then it will be post transformed to match what would have been produced if the geometry were
|
||||
* drawn with the total canvas matrix to begin with.
|
||||
*/
|
||||
class SK_API SkImageFilter : public SkFlattenable {
|
||||
public:
|
||||
enum MapDirection {
|
||||
kForward_MapDirection,
|
||||
kReverse_MapDirection,
|
||||
};
|
||||
/**
|
||||
* Map a device-space rect recursively forward or backward through the filter DAG.
|
||||
* kForward_MapDirection is used to determine which pixels of the destination canvas a source
|
||||
* image rect would touch after filtering. kReverse_MapDirection is used to determine which rect
|
||||
* of the source image would be required to fill the given rect (typically, clip bounds). Used
|
||||
* for clipping and temp-buffer allocations, so the result need not be exact, but should never
|
||||
* be smaller than the real answer. The default implementation recursively unions all input
|
||||
* bounds, or returns the source rect if no inputs.
|
||||
*
|
||||
* In kReverse mode, 'inputRect' is the device-space bounds of the input pixels. In kForward
|
||||
* mode it should always be null. If 'inputRect' is null in kReverse mode the resulting answer
|
||||
* may be incorrect.
|
||||
*/
|
||||
SkIRect filterBounds(const SkIRect& src, const SkMatrix& ctm,
|
||||
MapDirection, const SkIRect* inputRect = nullptr) const;
|
||||
|
||||
/**
|
||||
* Returns whether this image filter is a color filter and puts the color filter into the
|
||||
* "filterPtr" parameter if it can. Does nothing otherwise.
|
||||
* If this returns false, then the filterPtr is unchanged.
|
||||
* If this returns true, then if filterPtr is not null, it must be set to a ref'd colorfitler
|
||||
* (i.e. it may not be set to NULL).
|
||||
*/
|
||||
bool isColorFilterNode(SkColorFilter** filterPtr) const;
|
||||
|
||||
// DEPRECATED : use isColorFilterNode() instead
|
||||
bool asColorFilter(SkColorFilter** filterPtr) const {
|
||||
return this->isColorFilterNode(filterPtr);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 same
|
||||
* way.
|
||||
*/
|
||||
bool asAColorFilter(SkColorFilter** filterPtr) const;
|
||||
|
||||
/**
|
||||
* Returns the number of inputs this filter will accept (some inputs can be NULL).
|
||||
*/
|
||||
int countInputs() const;
|
||||
|
||||
/**
|
||||
* Returns the input filter at a given index, or NULL if no input is connected. The indices
|
||||
* used are filter-specific.
|
||||
*/
|
||||
const SkImageFilter* getInput(int i) const;
|
||||
|
||||
// Default impl returns union of all input bounds.
|
||||
virtual SkRect computeFastBounds(const SkRect& bounds) const;
|
||||
|
||||
// Can this filter DAG compute the resulting bounds of an object-space rectangle?
|
||||
bool canComputeFastBounds() const;
|
||||
|
||||
/**
|
||||
* If this filter can be represented by another filter + a localMatrix, return that filter,
|
||||
* else return null.
|
||||
*/
|
||||
sk_sp<SkImageFilter> makeWithLocalMatrix(const SkMatrix& matrix) const;
|
||||
|
||||
static sk_sp<SkImageFilter> Deserialize(const void* data, size_t size,
|
||||
const SkDeserialProcs* procs = nullptr) {
|
||||
return sk_sp<SkImageFilter>(static_cast<SkImageFilter*>(
|
||||
SkFlattenable::Deserialize(kSkImageFilter_Type, data, size, procs).release()));
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
sk_sp<SkImageFilter> refMe() const {
|
||||
return sk_ref_sp(const_cast<SkImageFilter*>(this));
|
||||
}
|
||||
|
||||
private:
|
||||
friend class SkImageFilter_Base;
|
||||
|
||||
using INHERITED = SkFlattenable;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* Copyright 2013 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkImageGenerator_DEFINED
|
||||
#define SkImageGenerator_DEFINED
|
||||
|
||||
#include "include/core/SkData.h"
|
||||
#include "include/core/SkImageInfo.h"
|
||||
#include "include/core/SkPixmap.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/core/SkYUVAPixmaps.h"
|
||||
#include "include/private/base/SkAPI.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
class SkRecorder;
|
||||
|
||||
class SK_API SkImageGenerator {
|
||||
public:
|
||||
/**
|
||||
* The PixelRef which takes ownership of this SkImageGenerator
|
||||
* will call the image generator's destructor.
|
||||
*/
|
||||
virtual ~SkImageGenerator() { }
|
||||
|
||||
uint32_t uniqueID() const { return fUniqueID; }
|
||||
|
||||
/**
|
||||
* Return a ref to the encoded (i.e. compressed) representation
|
||||
* of this data.
|
||||
*
|
||||
* If non-NULL is returned, the caller is responsible for calling
|
||||
* unref() on the data when it is finished.
|
||||
*/
|
||||
sk_sp<const SkData> refEncodedData() { return this->onRefEncodedData(); }
|
||||
|
||||
/**
|
||||
* Return the ImageInfo associated with this generator.
|
||||
*/
|
||||
const SkImageInfo& getInfo() const { return fInfo; }
|
||||
|
||||
/**
|
||||
* Can this generator be used to produce images that will be drawable to the specified context
|
||||
* (or to CPU, if context is nullptr)?
|
||||
*/
|
||||
bool isValid(SkRecorder* recorder) const { return this->onIsValid(recorder); }
|
||||
|
||||
/**
|
||||
* Will this generator produce protected content
|
||||
*/
|
||||
bool isProtected() const {
|
||||
return this->onIsProtected();
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode into the given pixels, a block of memory of size at
|
||||
* least (info.fHeight - 1) * rowBytes + (info.fWidth *
|
||||
* bytesPerPixel)
|
||||
*
|
||||
* Repeated calls to this function should give the same results,
|
||||
* allowing the PixelRef to be immutable.
|
||||
*
|
||||
* @param info A description of the format
|
||||
* expected by the caller. This can simply be identical
|
||||
* to the info returned by getInfo().
|
||||
*
|
||||
* This contract also allows the caller to specify
|
||||
* different output-configs, which the implementation can
|
||||
* decide to support or not.
|
||||
*
|
||||
* A size that does not match getInfo() implies a request
|
||||
* to scale. If the generator cannot perform this scale,
|
||||
* it will return false.
|
||||
*
|
||||
* @return true on success.
|
||||
*/
|
||||
bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes);
|
||||
|
||||
bool getPixels(const SkPixmap& pm) {
|
||||
return this->getPixels(pm.info(), pm.writable_addr(), pm.rowBytes());
|
||||
}
|
||||
|
||||
/**
|
||||
* If decoding to YUV is supported, this returns true. Otherwise, this
|
||||
* returns false and the caller will ignore output parameter yuvaPixmapInfo.
|
||||
*
|
||||
* @param supportedDataTypes Indicates the data type/planar config combinations that are
|
||||
* supported by the caller. If the generator supports decoding to
|
||||
* YUV(A), but not as a type in supportedDataTypes, this method
|
||||
* returns false.
|
||||
* @param yuvaPixmapInfo Output parameter that specifies the planar configuration, subsampling,
|
||||
* orientation, chroma siting, plane color types, and row bytes.
|
||||
*/
|
||||
bool queryYUVAInfo(const SkYUVAPixmapInfo::SupportedDataTypes& supportedDataTypes,
|
||||
SkYUVAPixmapInfo* yuvaPixmapInfo) const;
|
||||
|
||||
/**
|
||||
* Returns true on success and false on failure.
|
||||
* This always attempts to perform a full decode. To get the planar
|
||||
* configuration without decoding use queryYUVAInfo().
|
||||
*
|
||||
* @param yuvaPixmaps Contains preallocated pixmaps configured according to a successful call
|
||||
* to queryYUVAInfo().
|
||||
*/
|
||||
bool getYUVAPlanes(const SkYUVAPixmaps& yuvaPixmaps);
|
||||
|
||||
virtual bool isTextureGenerator() const { return false; }
|
||||
|
||||
protected:
|
||||
static constexpr int kNeedNewImageUniqueID = 0;
|
||||
|
||||
SkImageGenerator(const SkImageInfo& info, uint32_t uniqueId = kNeedNewImageUniqueID);
|
||||
|
||||
virtual sk_sp<const SkData> onRefEncodedData() { return nullptr; }
|
||||
|
||||
struct Options {};
|
||||
virtual bool onGetPixels(const SkImageInfo&, void*, size_t, const Options&) { return false; }
|
||||
virtual bool onIsValid(SkRecorder*) const { return true; }
|
||||
virtual bool onIsProtected() const { return false; }
|
||||
virtual bool onQueryYUVAInfo(const SkYUVAPixmapInfo::SupportedDataTypes&,
|
||||
SkYUVAPixmapInfo*) const { return false; }
|
||||
virtual bool onGetYUVAPlanes(const SkYUVAPixmaps&) { return false; }
|
||||
|
||||
const SkImageInfo fInfo;
|
||||
|
||||
private:
|
||||
const uint32_t fUniqueID;
|
||||
|
||||
SkImageGenerator(SkImageGenerator&&) = delete;
|
||||
SkImageGenerator(const SkImageGenerator&) = delete;
|
||||
SkImageGenerator& operator=(SkImageGenerator&&) = delete;
|
||||
SkImageGenerator& operator=(const SkImageGenerator&) = delete;
|
||||
};
|
||||
|
||||
#endif // SkImageGenerator_DEFINED
|
||||
|
|
@ -0,0 +1,634 @@
|
|||
/*
|
||||
* Copyright 2013 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkImageInfo_DEFINED
|
||||
#define SkImageInfo_DEFINED
|
||||
|
||||
#include "include/core/SkAlphaType.h"
|
||||
#include "include/core/SkColorType.h"
|
||||
#include "include/core/SkRect.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/core/SkSize.h"
|
||||
#include "include/private/base/SkAPI.h"
|
||||
#include "include/private/base/SkDebug.h"
|
||||
#include "include/private/base/SkMath.h"
|
||||
#include "include/private/base/SkTFitsIn.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
|
||||
class SkColorSpace;
|
||||
|
||||
/** Returns the number of bytes required to store a pixel, including unused padding.
|
||||
Returns zero if ct is kUnknown_SkColorType or invalid.
|
||||
|
||||
@return bytes per pixel
|
||||
*/
|
||||
SK_API int SkColorTypeBytesPerPixel(SkColorType ct);
|
||||
|
||||
/** Returns true if SkColorType always decodes alpha to 1.0, making the pixel
|
||||
fully opaque. If true, SkColorType does not reserve bits to encode alpha.
|
||||
|
||||
@return true if alpha is always set to 1.0
|
||||
*/
|
||||
SK_API bool SkColorTypeIsAlwaysOpaque(SkColorType ct);
|
||||
|
||||
/** Returns true if canonical can be set to a valid SkAlphaType for colorType. If
|
||||
there is more than one valid canonical SkAlphaType, set to alphaType, if valid.
|
||||
If true is returned and canonical is not nullptr, store valid SkAlphaType.
|
||||
|
||||
Returns false only if alphaType is kUnknown_SkAlphaType, color type is not
|
||||
kUnknown_SkColorType, and SkColorType is not always opaque. If false is returned,
|
||||
canonical is ignored.
|
||||
|
||||
@param canonical storage for SkAlphaType
|
||||
@return true if valid SkAlphaType can be associated with colorType
|
||||
*/
|
||||
SK_API bool SkColorTypeValidateAlphaType(SkColorType colorType, SkAlphaType alphaType,
|
||||
SkAlphaType* canonical = nullptr);
|
||||
|
||||
/** \enum SkImageInfo::SkYUVColorSpace
|
||||
Describes color range of YUV pixels. The color mapping from YUV to RGB varies
|
||||
depending on the source. YUV pixels may be generated by JPEG images, standard
|
||||
video streams, or high definition video streams. Each has its own mapping from
|
||||
YUV to RGB.
|
||||
|
||||
JPEG YUV values encode the full range of 0 to 255 for all three components.
|
||||
Video YUV values often range from 16 to 235 for Y and from 16 to 240 for U and V (limited).
|
||||
Details of encoding and conversion to RGB are described in YCbCr color space.
|
||||
|
||||
The identity colorspace exists to provide a utility mapping from Y to R, U to G and V to B.
|
||||
It can be used to visualize the YUV planes or to explicitly post process the YUV channels.
|
||||
*/
|
||||
enum SkYUVColorSpace : int {
|
||||
kJPEG_Full_SkYUVColorSpace, //!< describes full range
|
||||
kRec601_Limited_SkYUVColorSpace, //!< describes SDTV range
|
||||
kRec709_Full_SkYUVColorSpace, //!< describes HDTV range
|
||||
kRec709_Limited_SkYUVColorSpace,
|
||||
kBT2020_8bit_Full_SkYUVColorSpace, //!< describes UHDTV range, non-constant-luminance
|
||||
kBT2020_8bit_Limited_SkYUVColorSpace,
|
||||
kBT2020_10bit_Full_SkYUVColorSpace,
|
||||
kBT2020_10bit_Limited_SkYUVColorSpace,
|
||||
kBT2020_12bit_Full_SkYUVColorSpace,
|
||||
kBT2020_12bit_Limited_SkYUVColorSpace,
|
||||
kBT2020_16bit_Full_SkYUVColorSpace,
|
||||
kBT2020_16bit_Limited_SkYUVColorSpace,
|
||||
kFCC_Full_SkYUVColorSpace, //!< describes FCC range
|
||||
kFCC_Limited_SkYUVColorSpace,
|
||||
kSMPTE240_Full_SkYUVColorSpace, //!< describes SMPTE240M range
|
||||
kSMPTE240_Limited_SkYUVColorSpace,
|
||||
kYDZDX_Full_SkYUVColorSpace, //!< describes YDZDX range
|
||||
kYDZDX_Limited_SkYUVColorSpace,
|
||||
kGBR_Full_SkYUVColorSpace, //!< describes GBR range
|
||||
kGBR_Limited_SkYUVColorSpace,
|
||||
kYCgCo_8bit_Full_SkYUVColorSpace, //!< describes YCgCo matrix
|
||||
kYCgCo_8bit_Limited_SkYUVColorSpace,
|
||||
kYCgCo_10bit_Full_SkYUVColorSpace,
|
||||
kYCgCo_10bit_Limited_SkYUVColorSpace,
|
||||
kYCgCo_12bit_Full_SkYUVColorSpace,
|
||||
kYCgCo_12bit_Limited_SkYUVColorSpace,
|
||||
kYCgCo_16bit_Full_SkYUVColorSpace,
|
||||
kYCgCo_16bit_Limited_SkYUVColorSpace,
|
||||
kIdentity_SkYUVColorSpace, //!< maps Y->R, U->G, V->B
|
||||
|
||||
kLastEnum_SkYUVColorSpace = kIdentity_SkYUVColorSpace, //!< last valid value
|
||||
|
||||
// Legacy (deprecated) names:
|
||||
kJPEG_SkYUVColorSpace = kJPEG_Full_SkYUVColorSpace,
|
||||
kRec601_SkYUVColorSpace = kRec601_Limited_SkYUVColorSpace,
|
||||
kRec709_SkYUVColorSpace = kRec709_Limited_SkYUVColorSpace,
|
||||
kBT2020_SkYUVColorSpace = kBT2020_8bit_Limited_SkYUVColorSpace,
|
||||
};
|
||||
|
||||
SK_API bool SkYUVColorSpaceIsLimitedRange(SkYUVColorSpace cs);
|
||||
|
||||
/** \struct SkColorInfo
|
||||
Describes pixel and encoding. SkImageInfo can be created from SkColorInfo by
|
||||
providing dimensions.
|
||||
|
||||
It encodes how pixel bits describe alpha, transparency; color components red, blue,
|
||||
and green; and SkColorSpace, the range and linearity of colors.
|
||||
*/
|
||||
class SK_API SkColorInfo {
|
||||
public:
|
||||
/** Creates an SkColorInfo with kUnknown_SkColorType, kUnknown_SkAlphaType,
|
||||
and no SkColorSpace.
|
||||
|
||||
@return empty SkImageInfo
|
||||
*/
|
||||
SkColorInfo();
|
||||
~SkColorInfo();
|
||||
|
||||
/** Creates SkColorInfo from SkColorType ct, SkAlphaType at, and optionally SkColorSpace cs.
|
||||
|
||||
If SkColorSpace cs is nullptr and SkColorInfo is part of drawing source: SkColorSpace
|
||||
defaults to sRGB, mapping into SkSurface SkColorSpace.
|
||||
|
||||
Parameters are not validated to see if their values are legal, or that the
|
||||
combination is supported.
|
||||
@return created SkColorInfo
|
||||
*/
|
||||
SkColorInfo(SkColorType ct, SkAlphaType at, sk_sp<SkColorSpace> cs);
|
||||
|
||||
SkColorInfo(const SkColorInfo&);
|
||||
SkColorInfo(SkColorInfo&&);
|
||||
|
||||
SkColorInfo& operator=(const SkColorInfo&);
|
||||
SkColorInfo& operator=(SkColorInfo&&);
|
||||
|
||||
SkColorSpace* colorSpace() const;
|
||||
sk_sp<SkColorSpace> refColorSpace() const;
|
||||
SkColorType colorType() const { return fColorType; }
|
||||
SkAlphaType alphaType() const { return fAlphaType; }
|
||||
|
||||
bool isOpaque() const {
|
||||
return SkAlphaTypeIsOpaque(fAlphaType)
|
||||
|| SkColorTypeIsAlwaysOpaque(fColorType);
|
||||
}
|
||||
|
||||
bool gammaCloseToSRGB() const;
|
||||
|
||||
/** Does other represent the same color type, alpha type, and color space? */
|
||||
bool operator==(const SkColorInfo& other) const;
|
||||
|
||||
/** Does other represent a different color type, alpha type, or color space? */
|
||||
bool operator!=(const SkColorInfo& other) const;
|
||||
|
||||
/** Creates SkColorInfo with same SkColorType, SkColorSpace, with SkAlphaType set
|
||||
to newAlphaType.
|
||||
|
||||
Created SkColorInfo contains newAlphaType even if it is incompatible with
|
||||
SkColorType, in which case SkAlphaType in SkColorInfo is ignored.
|
||||
*/
|
||||
SkColorInfo makeAlphaType(SkAlphaType newAlphaType) const;
|
||||
|
||||
/** Creates new SkColorInfo with same SkAlphaType, SkColorSpace, with SkColorType
|
||||
set to newColorType.
|
||||
*/
|
||||
SkColorInfo makeColorType(SkColorType newColorType) const;
|
||||
|
||||
/** Creates SkColorInfo with same SkAlphaType, SkColorType, with SkColorSpace
|
||||
set to cs. cs may be nullptr.
|
||||
*/
|
||||
SkColorInfo makeColorSpace(sk_sp<SkColorSpace> cs) const;
|
||||
|
||||
/** Returns number of bytes per pixel required by SkColorType.
|
||||
Returns zero if colorType() is kUnknown_SkColorType.
|
||||
|
||||
@return bytes in pixel
|
||||
|
||||
example: https://fiddle.skia.org/c/@ImageInfo_bytesPerPixel
|
||||
*/
|
||||
int bytesPerPixel() const;
|
||||
|
||||
/** Returns bit shift converting row bytes to row pixels.
|
||||
Returns zero for kUnknown_SkColorType.
|
||||
|
||||
@return one of: 0, 1, 2, 3, 4; left shift to convert pixels to bytes
|
||||
|
||||
example: https://fiddle.skia.org/c/@ImageInfo_shiftPerPixel
|
||||
*/
|
||||
int shiftPerPixel() const;
|
||||
|
||||
private:
|
||||
sk_sp<SkColorSpace> fColorSpace;
|
||||
SkColorType fColorType = kUnknown_SkColorType;
|
||||
SkAlphaType fAlphaType = kUnknown_SkAlphaType;
|
||||
};
|
||||
|
||||
/** \struct SkImageInfo
|
||||
Describes pixel dimensions and encoding. SkBitmap, SkImage, PixMap, and SkSurface
|
||||
can be created from SkImageInfo. SkImageInfo can be retrieved from SkBitmap and
|
||||
SkPixmap, but not from SkImage and SkSurface. For example, SkImage and SkSurface
|
||||
implementations may defer pixel depth, so may not completely specify SkImageInfo.
|
||||
|
||||
SkImageInfo contains dimensions, the pixel integral width and height. It encodes
|
||||
how pixel bits describe alpha, transparency; color components red, blue,
|
||||
and green; and SkColorSpace, the range and linearity of colors.
|
||||
*/
|
||||
struct SK_API SkImageInfo {
|
||||
public:
|
||||
|
||||
/** Creates an empty SkImageInfo with kUnknown_SkColorType, kUnknown_SkAlphaType,
|
||||
a width and height of zero, and no SkColorSpace.
|
||||
|
||||
@return empty SkImageInfo
|
||||
*/
|
||||
SkImageInfo() = default;
|
||||
|
||||
/** Creates SkImageInfo from integral dimensions width and height, SkColorType ct,
|
||||
SkAlphaType at, and optionally SkColorSpace cs.
|
||||
|
||||
If SkColorSpace cs is nullptr and SkImageInfo is part of drawing source: SkColorSpace
|
||||
defaults to sRGB, mapping into SkSurface SkColorSpace.
|
||||
|
||||
Parameters are not validated to see if their values are legal, or that the
|
||||
combination is supported.
|
||||
|
||||
@param width pixel column count; must be zero or greater
|
||||
@param height pixel row count; must be zero or greater
|
||||
@param cs range of colors; may be nullptr
|
||||
@return created SkImageInfo
|
||||
*/
|
||||
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at);
|
||||
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at,
|
||||
sk_sp<SkColorSpace> cs);
|
||||
static SkImageInfo Make(SkISize dimensions, SkColorType ct, SkAlphaType at);
|
||||
static SkImageInfo Make(SkISize dimensions, SkColorType ct, SkAlphaType at,
|
||||
sk_sp<SkColorSpace> cs);
|
||||
|
||||
/** Creates SkImageInfo from integral dimensions and SkColorInfo colorInfo,
|
||||
|
||||
Parameters are not validated to see if their values are legal, or that the
|
||||
combination is supported.
|
||||
|
||||
@param dimensions pixel column and row count; must be zeros or greater
|
||||
@param SkColorInfo the pixel encoding consisting of SkColorType, SkAlphaType, and
|
||||
SkColorSpace (which may be nullptr)
|
||||
@return created SkImageInfo
|
||||
*/
|
||||
static SkImageInfo Make(SkISize dimensions, const SkColorInfo& colorInfo) {
|
||||
return SkImageInfo(dimensions, colorInfo);
|
||||
}
|
||||
static SkImageInfo Make(SkISize dimensions, SkColorInfo&& colorInfo) {
|
||||
return SkImageInfo(dimensions, std::move(colorInfo));
|
||||
}
|
||||
|
||||
/** Creates SkImageInfo from integral dimensions width and height, kN32_SkColorType,
|
||||
SkAlphaType at, and optionally SkColorSpace cs. kN32_SkColorType will equal either
|
||||
kBGRA_8888_SkColorType or kRGBA_8888_SkColorType, whichever is optimal.
|
||||
|
||||
If SkColorSpace cs is nullptr and SkImageInfo is part of drawing source: SkColorSpace
|
||||
defaults to sRGB, mapping into SkSurface SkColorSpace.
|
||||
|
||||
Parameters are not validated to see if their values are legal, or that the
|
||||
combination is supported.
|
||||
|
||||
@param width pixel column count; must be zero or greater
|
||||
@param height pixel row count; must be zero or greater
|
||||
@param cs range of colors; may be nullptr
|
||||
@return created SkImageInfo
|
||||
*/
|
||||
static SkImageInfo MakeN32(int width, int height, SkAlphaType at);
|
||||
static SkImageInfo MakeN32(int width, int height, SkAlphaType at, sk_sp<SkColorSpace> cs);
|
||||
|
||||
/** Creates SkImageInfo from integral dimensions width and height, kN32_SkColorType,
|
||||
SkAlphaType at, with sRGB SkColorSpace.
|
||||
|
||||
Parameters are not validated to see if their values are legal, or that the
|
||||
combination is supported.
|
||||
|
||||
@param width pixel column count; must be zero or greater
|
||||
@param height pixel row count; must be zero or greater
|
||||
@return created SkImageInfo
|
||||
|
||||
example: https://fiddle.skia.org/c/@ImageInfo_MakeS32
|
||||
*/
|
||||
static SkImageInfo MakeS32(int width, int height, SkAlphaType at);
|
||||
|
||||
/** Creates SkImageInfo from integral dimensions width and height, kN32_SkColorType,
|
||||
kPremul_SkAlphaType, with optional SkColorSpace.
|
||||
|
||||
If SkColorSpace cs is nullptr and SkImageInfo is part of drawing source: SkColorSpace
|
||||
defaults to sRGB, mapping into SkSurface SkColorSpace.
|
||||
|
||||
Parameters are not validated to see if their values are legal, or that the
|
||||
combination is supported.
|
||||
|
||||
@param width pixel column count; must be zero or greater
|
||||
@param height pixel row count; must be zero or greater
|
||||
@param cs range of colors; may be nullptr
|
||||
@return created SkImageInfo
|
||||
*/
|
||||
static SkImageInfo MakeN32Premul(int width, int height);
|
||||
static SkImageInfo MakeN32Premul(int width, int height, sk_sp<SkColorSpace> cs);
|
||||
|
||||
/** Creates SkImageInfo from integral dimensions width and height, kN32_SkColorType,
|
||||
kPremul_SkAlphaType, with SkColorSpace set to nullptr.
|
||||
|
||||
If SkImageInfo is part of drawing source: SkColorSpace defaults to sRGB, mapping
|
||||
into SkSurface SkColorSpace.
|
||||
|
||||
Parameters are not validated to see if their values are legal, or that the
|
||||
combination is supported.
|
||||
|
||||
@param dimensions width and height, each must be zero or greater
|
||||
@param cs range of colors; may be nullptr
|
||||
@return created SkImageInfo
|
||||
*/
|
||||
static SkImageInfo MakeN32Premul(SkISize dimensions);
|
||||
static SkImageInfo MakeN32Premul(SkISize dimensions, sk_sp<SkColorSpace> cs);
|
||||
|
||||
/** Creates SkImageInfo from integral dimensions width and height, kAlpha_8_SkColorType,
|
||||
kPremul_SkAlphaType, with SkColorSpace set to nullptr.
|
||||
|
||||
@param width pixel column count; must be zero or greater
|
||||
@param height pixel row count; must be zero or greater
|
||||
@return created SkImageInfo
|
||||
*/
|
||||
static SkImageInfo MakeA8(int width, int height);
|
||||
/** Creates SkImageInfo from integral dimensions, kAlpha_8_SkColorType,
|
||||
kPremul_SkAlphaType, with SkColorSpace set to nullptr.
|
||||
|
||||
@param dimensions pixel row and column count; must be zero or greater
|
||||
@return created SkImageInfo
|
||||
*/
|
||||
static SkImageInfo MakeA8(SkISize dimensions);
|
||||
|
||||
/** Creates SkImageInfo from integral dimensions width and height, kUnknown_SkColorType,
|
||||
kUnknown_SkAlphaType, with SkColorSpace set to nullptr.
|
||||
|
||||
Returned SkImageInfo as part of source does not draw, and as part of destination
|
||||
can not be drawn to.
|
||||
|
||||
@param width pixel column count; must be zero or greater
|
||||
@param height pixel row count; must be zero or greater
|
||||
@return created SkImageInfo
|
||||
*/
|
||||
static SkImageInfo MakeUnknown(int width, int height);
|
||||
|
||||
/** Creates SkImageInfo from integral dimensions width and height set to zero,
|
||||
kUnknown_SkColorType, kUnknown_SkAlphaType, with SkColorSpace set to nullptr.
|
||||
|
||||
Returned SkImageInfo as part of source does not draw, and as part of destination
|
||||
can not be drawn to.
|
||||
|
||||
@return created SkImageInfo
|
||||
*/
|
||||
static SkImageInfo MakeUnknown() {
|
||||
return MakeUnknown(0, 0);
|
||||
}
|
||||
|
||||
/** Returns pixel count in each row.
|
||||
|
||||
@return pixel width
|
||||
*/
|
||||
int width() const { return fDimensions.width(); }
|
||||
|
||||
/** Returns pixel row count.
|
||||
|
||||
@return pixel height
|
||||
*/
|
||||
int height() const { return fDimensions.height(); }
|
||||
|
||||
SkColorType colorType() const { return fColorInfo.colorType(); }
|
||||
|
||||
SkAlphaType alphaType() const { return fColorInfo.alphaType(); }
|
||||
|
||||
/** Returns SkColorSpace, the range of colors. The reference count of
|
||||
SkColorSpace is unchanged. The returned SkColorSpace is immutable.
|
||||
|
||||
@return SkColorSpace, or nullptr
|
||||
*/
|
||||
SkColorSpace* colorSpace() const;
|
||||
|
||||
/** Returns smart pointer to SkColorSpace, the range of colors. The smart pointer
|
||||
tracks the number of objects sharing this SkColorSpace reference so the memory
|
||||
is released when the owners destruct.
|
||||
|
||||
The returned SkColorSpace is immutable.
|
||||
|
||||
@return SkColorSpace wrapped in a smart pointer
|
||||
*/
|
||||
sk_sp<SkColorSpace> refColorSpace() const;
|
||||
|
||||
/** Returns if SkImageInfo describes an empty area of pixels by checking if either
|
||||
width or height is zero or smaller.
|
||||
|
||||
@return true if either dimension is zero or smaller
|
||||
*/
|
||||
bool isEmpty() const { return fDimensions.isEmpty(); }
|
||||
|
||||
/** Returns the dimensionless SkColorInfo that represents the same color type,
|
||||
alpha type, and color space as this SkImageInfo.
|
||||
*/
|
||||
const SkColorInfo& colorInfo() const { return fColorInfo; }
|
||||
|
||||
/** Returns true if SkAlphaType is set to hint that all pixels are opaque; their
|
||||
alpha value is implicitly or explicitly 1.0. If true, and all pixels are
|
||||
not opaque, Skia may draw incorrectly.
|
||||
|
||||
Does not check if SkColorType allows alpha, or if any pixel value has
|
||||
transparency.
|
||||
|
||||
@return true if SkAlphaType is kOpaque_SkAlphaType
|
||||
*/
|
||||
bool isOpaque() const { return fColorInfo.isOpaque(); }
|
||||
|
||||
/** Returns SkISize { width(), height() }.
|
||||
|
||||
@return integral size of width() and height()
|
||||
*/
|
||||
SkISize dimensions() const { return fDimensions; }
|
||||
|
||||
/** Returns SkIRect { 0, 0, width(), height() }.
|
||||
|
||||
@return integral rectangle from origin to width() and height()
|
||||
*/
|
||||
SkIRect bounds() const { return SkIRect::MakeSize(fDimensions); }
|
||||
|
||||
/** Returns true if associated SkColorSpace is not nullptr, and SkColorSpace gamma
|
||||
is approximately the same as sRGB.
|
||||
This includes the
|
||||
|
||||
@return true if SkColorSpace gamma is approximately the same as sRGB
|
||||
*/
|
||||
bool gammaCloseToSRGB() const { return fColorInfo.gammaCloseToSRGB(); }
|
||||
|
||||
/** Creates SkImageInfo with the same SkColorType, SkColorSpace, and SkAlphaType,
|
||||
with dimensions set to width and height.
|
||||
|
||||
@param newWidth pixel column count; must be zero or greater
|
||||
@param newHeight pixel row count; must be zero or greater
|
||||
@return created SkImageInfo
|
||||
*/
|
||||
SkImageInfo makeWH(int newWidth, int newHeight) const {
|
||||
return Make({newWidth, newHeight}, fColorInfo);
|
||||
}
|
||||
|
||||
/** Creates SkImageInfo with the same SkColorType, SkColorSpace, and SkAlphaType,
|
||||
with dimensions set to newDimensions.
|
||||
|
||||
@param newSize pixel column and row count; must be zero or greater
|
||||
@return created SkImageInfo
|
||||
*/
|
||||
SkImageInfo makeDimensions(SkISize newSize) const {
|
||||
return Make(newSize, fColorInfo);
|
||||
}
|
||||
|
||||
/** Creates SkImageInfo with same SkColorType, SkColorSpace, width, and height,
|
||||
with SkAlphaType set to newAlphaType.
|
||||
|
||||
Created SkImageInfo contains newAlphaType even if it is incompatible with
|
||||
SkColorType, in which case SkAlphaType in SkImageInfo is ignored.
|
||||
|
||||
@return created SkImageInfo
|
||||
*/
|
||||
SkImageInfo makeAlphaType(SkAlphaType newAlphaType) const {
|
||||
return Make(fDimensions, fColorInfo.makeAlphaType(newAlphaType));
|
||||
}
|
||||
|
||||
/** Creates SkImageInfo with same SkAlphaType, SkColorSpace, width, and height,
|
||||
with SkColorType set to newColorType.
|
||||
|
||||
@return created SkImageInfo
|
||||
*/
|
||||
SkImageInfo makeColorType(SkColorType newColorType) const {
|
||||
return Make(fDimensions, fColorInfo.makeColorType(newColorType));
|
||||
}
|
||||
|
||||
/** Creates SkImageInfo with same SkAlphaType, SkColorType, width, and height,
|
||||
with SkColorSpace set to cs.
|
||||
|
||||
@param cs range of colors; may be nullptr
|
||||
@return created SkImageInfo
|
||||
*/
|
||||
SkImageInfo makeColorSpace(sk_sp<SkColorSpace> cs) const;
|
||||
|
||||
/** Returns number of bytes per pixel required by SkColorType.
|
||||
Returns zero if colorType( is kUnknown_SkColorType.
|
||||
|
||||
@return bytes in pixel
|
||||
*/
|
||||
int bytesPerPixel() const { return fColorInfo.bytesPerPixel(); }
|
||||
|
||||
/** Returns bit shift converting row bytes to row pixels.
|
||||
Returns zero for kUnknown_SkColorType.
|
||||
|
||||
@return one of: 0, 1, 2, 3; left shift to convert pixels to bytes
|
||||
*/
|
||||
int shiftPerPixel() const { return fColorInfo.shiftPerPixel(); }
|
||||
|
||||
/** Returns minimum bytes per row, computed from pixel width() and SkColorType, which
|
||||
specifies bytesPerPixel(). SkBitmap maximum value for row bytes must fit
|
||||
in 31 bits.
|
||||
|
||||
@return width() times bytesPerPixel() as unsigned 64-bit integer
|
||||
*/
|
||||
uint64_t minRowBytes64() const {
|
||||
return (uint64_t)sk_64_mul(this->width(), this->bytesPerPixel());
|
||||
}
|
||||
|
||||
/** Returns minimum bytes per row, computed from pixel width() and SkColorType, which
|
||||
specifies bytesPerPixel(). SkBitmap maximum value for row bytes must fit
|
||||
in 31 bits.
|
||||
|
||||
@return width() times bytesPerPixel() as size_t
|
||||
*/
|
||||
size_t minRowBytes() const {
|
||||
uint64_t minRowBytes = this->minRowBytes64();
|
||||
if (!SkTFitsIn<int32_t>(minRowBytes)) {
|
||||
return 0;
|
||||
}
|
||||
return (size_t)minRowBytes;
|
||||
}
|
||||
|
||||
/** Returns byte offset of pixel from pixel base address.
|
||||
|
||||
Asserts in debug build if x or y is outside of bounds. Does not assert if
|
||||
rowBytes is smaller than minRowBytes(), even though result may be incorrect.
|
||||
|
||||
@param x column index, zero or greater, and less than width()
|
||||
@param y row index, zero or greater, and less than height()
|
||||
@param rowBytes size of pixel row or larger
|
||||
@return offset within pixel array
|
||||
|
||||
example: https://fiddle.skia.org/c/@ImageInfo_computeOffset
|
||||
*/
|
||||
size_t computeOffset(int x, int y, size_t rowBytes) const;
|
||||
|
||||
/** Compares SkImageInfo with other, and returns true if width, height, SkColorType,
|
||||
SkAlphaType, and SkColorSpace are equivalent.
|
||||
|
||||
@param other SkImageInfo to compare
|
||||
@return true if SkImageInfo equals other
|
||||
*/
|
||||
bool operator==(const SkImageInfo& other) const {
|
||||
return fDimensions == other.fDimensions && fColorInfo == other.fColorInfo;
|
||||
}
|
||||
|
||||
/** Compares SkImageInfo with other, and returns true if width, height, SkColorType,
|
||||
SkAlphaType, and SkColorSpace are not equivalent.
|
||||
|
||||
@param other SkImageInfo to compare
|
||||
@return true if SkImageInfo is not equal to other
|
||||
*/
|
||||
bool operator!=(const SkImageInfo& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
/** Returns storage required by pixel array, given SkImageInfo dimensions, SkColorType,
|
||||
and rowBytes. rowBytes is assumed to be at least as large as minRowBytes().
|
||||
|
||||
Returns zero if height is zero.
|
||||
Returns SIZE_MAX if answer exceeds the range of size_t.
|
||||
|
||||
@param rowBytes size of pixel row or larger
|
||||
@return memory required by pixel buffer
|
||||
*/
|
||||
size_t computeByteSize(size_t rowBytes) const;
|
||||
|
||||
/** Returns storage required by pixel array, given SkImageInfo dimensions, and
|
||||
SkColorType. Uses minRowBytes() to compute bytes for pixel row.
|
||||
|
||||
Returns zero if height is zero.
|
||||
Returns SIZE_MAX if answer exceeds the range of size_t.
|
||||
|
||||
@return least memory required by pixel buffer
|
||||
*/
|
||||
size_t computeMinByteSize() const {
|
||||
return this->computeByteSize(this->minRowBytes());
|
||||
}
|
||||
|
||||
/** Returns true if byteSize equals SIZE_MAX. computeByteSize() and
|
||||
computeMinByteSize() return SIZE_MAX if size_t can not hold buffer size.
|
||||
|
||||
@param byteSize result of computeByteSize() or computeMinByteSize()
|
||||
@return true if computeByteSize() or computeMinByteSize() result exceeds size_t
|
||||
*/
|
||||
static bool ByteSizeOverflowed(size_t byteSize) {
|
||||
return SIZE_MAX == byteSize;
|
||||
}
|
||||
|
||||
/** Returns true if rowBytes is valid for this SkImageInfo.
|
||||
|
||||
@param rowBytes size of pixel row including padding
|
||||
@return true if rowBytes is large enough to contain pixel row and is properly
|
||||
aligned
|
||||
*/
|
||||
bool validRowBytes(size_t rowBytes) const {
|
||||
if (rowBytes < this->minRowBytes64()) {
|
||||
return false;
|
||||
}
|
||||
int shift = this->shiftPerPixel();
|
||||
size_t alignedRowBytes = rowBytes >> shift << shift;
|
||||
return alignedRowBytes == rowBytes;
|
||||
}
|
||||
|
||||
/** Creates an empty SkImageInfo with kUnknown_SkColorType, kUnknown_SkAlphaType,
|
||||
a width and height of zero, and no SkColorSpace.
|
||||
*/
|
||||
void reset() { *this = {}; }
|
||||
|
||||
/** Asserts if internal values are illegal or inconsistent. Only available if
|
||||
SK_DEBUG is defined at compile time.
|
||||
*/
|
||||
SkDEBUGCODE(void validate() const;)
|
||||
|
||||
private:
|
||||
SkColorInfo fColorInfo;
|
||||
SkISize fDimensions = {0, 0};
|
||||
|
||||
SkImageInfo(SkISize dimensions, const SkColorInfo& colorInfo)
|
||||
: fColorInfo(colorInfo), fDimensions(dimensions) {}
|
||||
|
||||
SkImageInfo(SkISize dimensions, SkColorInfo&& colorInfo)
|
||||
: fColorInfo(std::move(colorInfo)), fDimensions(dimensions) {}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,442 @@
|
|||
/*
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkM44_DEFINED
|
||||
#define SkM44_DEFINED
|
||||
|
||||
#include "include/core/SkMatrix.h"
|
||||
#include "include/core/SkScalar.h"
|
||||
#include "include/core/SkTypes.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
struct SkRect;
|
||||
|
||||
struct SK_API SkV2 {
|
||||
float x, y;
|
||||
|
||||
bool operator==(SkV2 v) const { return x == v.x && y == v.y; }
|
||||
bool operator!=(SkV2 v) const { return !(*this == v); }
|
||||
|
||||
static SkScalar Dot(SkV2 a, SkV2 b) { return a.x * b.x + a.y * b.y; }
|
||||
static SkScalar Cross(SkV2 a, SkV2 b) { return a.x * b.y - a.y * b.x; }
|
||||
static SkV2 Normalize(SkV2 v) { return v * (1.0f / v.length()); }
|
||||
|
||||
SkV2 operator-() const { return {-x, -y}; }
|
||||
SkV2 operator+(SkV2 v) const { return {x+v.x, y+v.y}; }
|
||||
SkV2 operator-(SkV2 v) const { return {x-v.x, y-v.y}; }
|
||||
|
||||
SkV2 operator*(SkV2 v) const { return {x*v.x, y*v.y}; }
|
||||
friend SkV2 operator*(SkV2 v, SkScalar s) { return {v.x*s, v.y*s}; }
|
||||
friend SkV2 operator*(SkScalar s, SkV2 v) { return {v.x*s, v.y*s}; }
|
||||
friend SkV2 operator/(SkV2 v, SkScalar s) { return {v.x/s, v.y/s}; }
|
||||
friend SkV2 operator/(SkScalar s, SkV2 v) { return {s/v.x, s/v.y}; }
|
||||
|
||||
void operator+=(SkV2 v) { *this = *this + v; }
|
||||
void operator-=(SkV2 v) { *this = *this - v; }
|
||||
void operator*=(SkV2 v) { *this = *this * v; }
|
||||
void operator*=(SkScalar s) { *this = *this * s; }
|
||||
void operator/=(SkScalar s) { *this = *this / s; }
|
||||
|
||||
SkScalar lengthSquared() const { return Dot(*this, *this); }
|
||||
SkScalar length() const { return SkScalarSqrt(this->lengthSquared()); }
|
||||
|
||||
SkScalar dot(SkV2 v) const { return Dot(*this, v); }
|
||||
SkScalar cross(SkV2 v) const { return Cross(*this, v); }
|
||||
SkV2 normalize() const { return Normalize(*this); }
|
||||
|
||||
const float* ptr() const { return &x; }
|
||||
float* ptr() { return &x; }
|
||||
};
|
||||
|
||||
struct SK_API SkV3 {
|
||||
float x, y, z;
|
||||
|
||||
bool operator==(const SkV3& v) const {
|
||||
return x == v.x && y == v.y && z == v.z;
|
||||
}
|
||||
bool operator!=(const SkV3& v) const { return !(*this == v); }
|
||||
|
||||
static SkScalar Dot(const SkV3& a, const SkV3& b) { return a.x*b.x + a.y*b.y + a.z*b.z; }
|
||||
static SkV3 Cross(const SkV3& a, const SkV3& b) {
|
||||
return { a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x };
|
||||
}
|
||||
static SkV3 Normalize(const SkV3& v) { return v * (1.0f / v.length()); }
|
||||
|
||||
SkV3 operator-() const { return {-x, -y, -z}; }
|
||||
SkV3 operator+(const SkV3& v) const { return { x + v.x, y + v.y, z + v.z }; }
|
||||
SkV3 operator-(const SkV3& v) const { return { x - v.x, y - v.y, z - v.z }; }
|
||||
|
||||
SkV3 operator*(const SkV3& v) const {
|
||||
return { x*v.x, y*v.y, z*v.z };
|
||||
}
|
||||
friend SkV3 operator*(const SkV3& v, SkScalar s) {
|
||||
return { v.x*s, v.y*s, v.z*s };
|
||||
}
|
||||
friend SkV3 operator*(SkScalar s, const SkV3& v) { return v*s; }
|
||||
|
||||
void operator+=(SkV3 v) { *this = *this + v; }
|
||||
void operator-=(SkV3 v) { *this = *this - v; }
|
||||
void operator*=(SkV3 v) { *this = *this * v; }
|
||||
void operator*=(SkScalar s) { *this = *this * s; }
|
||||
|
||||
SkScalar lengthSquared() const { return Dot(*this, *this); }
|
||||
SkScalar length() const { return SkScalarSqrt(Dot(*this, *this)); }
|
||||
|
||||
SkScalar dot(const SkV3& v) const { return Dot(*this, v); }
|
||||
SkV3 cross(const SkV3& v) const { return Cross(*this, v); }
|
||||
SkV3 normalize() const { return Normalize(*this); }
|
||||
|
||||
const float* ptr() const { return &x; }
|
||||
float* ptr() { return &x; }
|
||||
};
|
||||
|
||||
struct SK_API SkV4 {
|
||||
float x, y, z, w;
|
||||
|
||||
bool operator==(const SkV4& v) const {
|
||||
return x == v.x && y == v.y && z == v.z && w == v.w;
|
||||
}
|
||||
bool operator!=(const SkV4& v) const { return !(*this == v); }
|
||||
|
||||
static SkScalar Dot(const SkV4& a, const SkV4& b) {
|
||||
return a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w;
|
||||
}
|
||||
static SkV4 Normalize(const SkV4& v) { return v * (1.0f / v.length()); }
|
||||
|
||||
SkV4 operator-() const { return {-x, -y, -z, -w}; }
|
||||
SkV4 operator+(const SkV4& v) const { return { x + v.x, y + v.y, z + v.z, w + v.w }; }
|
||||
SkV4 operator-(const SkV4& v) const { return { x - v.x, y - v.y, z - v.z, w - v.w }; }
|
||||
|
||||
SkV4 operator*(const SkV4& v) const {
|
||||
return { x*v.x, y*v.y, z*v.z, w*v.w };
|
||||
}
|
||||
friend SkV4 operator*(const SkV4& v, SkScalar s) {
|
||||
return { v.x*s, v.y*s, v.z*s, v.w*s };
|
||||
}
|
||||
friend SkV4 operator*(SkScalar s, const SkV4& v) { return v*s; }
|
||||
|
||||
SkScalar lengthSquared() const { return Dot(*this, *this); }
|
||||
SkScalar length() const { return SkScalarSqrt(Dot(*this, *this)); }
|
||||
|
||||
SkScalar dot(const SkV4& v) const { return Dot(*this, v); }
|
||||
SkV4 normalize() const { return Normalize(*this); }
|
||||
|
||||
const float* ptr() const { return &x; }
|
||||
float* ptr() { return &x; }
|
||||
|
||||
float operator[](int i) const {
|
||||
SkASSERT(i >= 0 && i < 4);
|
||||
return this->ptr()[i];
|
||||
}
|
||||
float& operator[](int i) {
|
||||
SkASSERT(i >= 0 && i < 4);
|
||||
return this->ptr()[i];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 4x4 matrix used by SkCanvas and other parts of Skia.
|
||||
*
|
||||
* Skia assumes a right-handed coordinate system:
|
||||
* +X goes to the right
|
||||
* +Y goes down
|
||||
* +Z goes into the screen (away from the viewer)
|
||||
*/
|
||||
class SK_API SkM44 {
|
||||
public:
|
||||
SkM44(const SkM44& src) = default;
|
||||
SkM44& operator=(const SkM44& src) = default;
|
||||
|
||||
constexpr SkM44()
|
||||
: fMat{1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, 1}
|
||||
{}
|
||||
|
||||
SkM44(const SkM44& a, const SkM44& b) {
|
||||
this->setConcat(a, b);
|
||||
}
|
||||
|
||||
enum Uninitialized_Constructor {
|
||||
kUninitialized_Constructor
|
||||
};
|
||||
explicit SkM44(Uninitialized_Constructor) {}
|
||||
|
||||
enum NaN_Constructor {
|
||||
kNaN_Constructor
|
||||
};
|
||||
constexpr SkM44(NaN_Constructor)
|
||||
: fMat{SK_ScalarNaN, SK_ScalarNaN, SK_ScalarNaN, SK_ScalarNaN,
|
||||
SK_ScalarNaN, SK_ScalarNaN, SK_ScalarNaN, SK_ScalarNaN,
|
||||
SK_ScalarNaN, SK_ScalarNaN, SK_ScalarNaN, SK_ScalarNaN,
|
||||
SK_ScalarNaN, SK_ScalarNaN, SK_ScalarNaN, SK_ScalarNaN}
|
||||
{}
|
||||
|
||||
/**
|
||||
* The constructor parameters are in row-major order.
|
||||
*/
|
||||
constexpr SkM44(SkScalar m0, SkScalar m4, SkScalar m8, SkScalar m12,
|
||||
SkScalar m1, SkScalar m5, SkScalar m9, SkScalar m13,
|
||||
SkScalar m2, SkScalar m6, SkScalar m10, SkScalar m14,
|
||||
SkScalar m3, SkScalar m7, SkScalar m11, SkScalar m15)
|
||||
// fMat is column-major order in memory.
|
||||
: fMat{m0, m1, m2, m3,
|
||||
m4, m5, m6, m7,
|
||||
m8, m9, m10, m11,
|
||||
m12, m13, m14, m15}
|
||||
{}
|
||||
|
||||
static SkM44 Rows(const SkV4& r0, const SkV4& r1, const SkV4& r2, const SkV4& r3) {
|
||||
SkM44 m(kUninitialized_Constructor);
|
||||
m.setRow(0, r0);
|
||||
m.setRow(1, r1);
|
||||
m.setRow(2, r2);
|
||||
m.setRow(3, r3);
|
||||
return m;
|
||||
}
|
||||
static SkM44 Cols(const SkV4& c0, const SkV4& c1, const SkV4& c2, const SkV4& c3) {
|
||||
SkM44 m(kUninitialized_Constructor);
|
||||
m.setCol(0, c0);
|
||||
m.setCol(1, c1);
|
||||
m.setCol(2, c2);
|
||||
m.setCol(3, c3);
|
||||
return m;
|
||||
}
|
||||
|
||||
static SkM44 RowMajor(const SkScalar r[16]) {
|
||||
return SkM44(r[ 0], r[ 1], r[ 2], r[ 3],
|
||||
r[ 4], r[ 5], r[ 6], r[ 7],
|
||||
r[ 8], r[ 9], r[10], r[11],
|
||||
r[12], r[13], r[14], r[15]);
|
||||
}
|
||||
static SkM44 ColMajor(const SkScalar c[16]) {
|
||||
return SkM44(c[0], c[4], c[ 8], c[12],
|
||||
c[1], c[5], c[ 9], c[13],
|
||||
c[2], c[6], c[10], c[14],
|
||||
c[3], c[7], c[11], c[15]);
|
||||
}
|
||||
|
||||
static SkM44 Translate(SkScalar x, SkScalar y, SkScalar z = 0) {
|
||||
return SkM44(1, 0, 0, x,
|
||||
0, 1, 0, y,
|
||||
0, 0, 1, z,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
static SkM44 Scale(SkScalar x, SkScalar y, SkScalar z = 1) {
|
||||
return SkM44(x, 0, 0, 0,
|
||||
0, y, 0, 0,
|
||||
0, 0, z, 0,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
static SkM44 Rotate(SkV3 axis, SkScalar radians) {
|
||||
SkM44 m(kUninitialized_Constructor);
|
||||
m.setRotate(axis, radians);
|
||||
return m;
|
||||
}
|
||||
|
||||
// Scales and translates 'src' to fill 'dst' exactly.
|
||||
static SkM44 RectToRect(const SkRect& src, const SkRect& dst);
|
||||
|
||||
static SkM44 LookAt(const SkV3& eye, const SkV3& center, const SkV3& up);
|
||||
static SkM44 Perspective(float near, float far, float angle);
|
||||
|
||||
bool operator==(const SkM44& other) const;
|
||||
bool operator!=(const SkM44& other) const {
|
||||
return !(other == *this);
|
||||
}
|
||||
|
||||
void getColMajor(SkScalar v[]) const {
|
||||
memcpy(v, fMat, sizeof(fMat));
|
||||
}
|
||||
void getRowMajor(SkScalar v[]) const;
|
||||
|
||||
SkScalar rc(int r, int c) const {
|
||||
SkASSERT(r >= 0 && r <= 3);
|
||||
SkASSERT(c >= 0 && c <= 3);
|
||||
return fMat[c*4 + r];
|
||||
}
|
||||
void setRC(int r, int c, SkScalar value) {
|
||||
SkASSERT(r >= 0 && r <= 3);
|
||||
SkASSERT(c >= 0 && c <= 3);
|
||||
fMat[c*4 + r] = value;
|
||||
}
|
||||
|
||||
SkV4 row(int i) const {
|
||||
SkASSERT(i >= 0 && i <= 3);
|
||||
return {fMat[i + 0], fMat[i + 4], fMat[i + 8], fMat[i + 12]};
|
||||
}
|
||||
SkV4 col(int i) const {
|
||||
SkASSERT(i >= 0 && i <= 3);
|
||||
return {fMat[i*4 + 0], fMat[i*4 + 1], fMat[i*4 + 2], fMat[i*4 + 3]};
|
||||
}
|
||||
|
||||
void setRow(int i, const SkV4& v) {
|
||||
SkASSERT(i >= 0 && i <= 3);
|
||||
fMat[i + 0] = v.x;
|
||||
fMat[i + 4] = v.y;
|
||||
fMat[i + 8] = v.z;
|
||||
fMat[i + 12] = v.w;
|
||||
}
|
||||
void setCol(int i, const SkV4& v) {
|
||||
SkASSERT(i >= 0 && i <= 3);
|
||||
memcpy(&fMat[i*4], v.ptr(), sizeof(v));
|
||||
}
|
||||
|
||||
SkM44& setIdentity() {
|
||||
*this = { 1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, 1 };
|
||||
return *this;
|
||||
}
|
||||
|
||||
SkM44& setTranslate(SkScalar x, SkScalar y, SkScalar z = 0) {
|
||||
*this = { 1, 0, 0, x,
|
||||
0, 1, 0, y,
|
||||
0, 0, 1, z,
|
||||
0, 0, 0, 1 };
|
||||
return *this;
|
||||
}
|
||||
|
||||
SkM44& setScale(SkScalar x, SkScalar y, SkScalar z = 1) {
|
||||
*this = { x, 0, 0, 0,
|
||||
0, y, 0, 0,
|
||||
0, 0, z, 0,
|
||||
0, 0, 0, 1 };
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this matrix to rotate about the specified unit-length axis vector,
|
||||
* by an angle specified by its sin() and cos().
|
||||
*
|
||||
* This does not attempt to verify that axis.length() == 1 or that the sin,cos values
|
||||
* are correct.
|
||||
*/
|
||||
SkM44& setRotateUnitSinCos(SkV3 axis, SkScalar sinAngle, SkScalar cosAngle);
|
||||
|
||||
/**
|
||||
* Set this matrix to rotate about the specified unit-length axis vector,
|
||||
* by an angle specified in radians.
|
||||
*
|
||||
* This does not attempt to verify that axis.length() == 1.
|
||||
*/
|
||||
SkM44& setRotateUnit(SkV3 axis, SkScalar radians) {
|
||||
return this->setRotateUnitSinCos(axis, SkScalarSin(radians), SkScalarCos(radians));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this matrix to rotate about the specified axis vector,
|
||||
* by an angle specified in radians.
|
||||
*
|
||||
* Note: axis is not assumed to be unit-length, so it will be normalized internally.
|
||||
* If axis is already unit-length, call setRotateAboutUnitRadians() instead.
|
||||
*/
|
||||
SkM44& setRotate(SkV3 axis, SkScalar radians);
|
||||
|
||||
SkM44& setConcat(const SkM44& a, const SkM44& b);
|
||||
|
||||
friend SkM44 operator*(const SkM44& a, const SkM44& b) {
|
||||
return SkM44(a, b);
|
||||
}
|
||||
|
||||
SkM44& preConcat(const SkM44& m) {
|
||||
return this->setConcat(*this, m);
|
||||
}
|
||||
|
||||
SkM44& postConcat(const SkM44& m) {
|
||||
return this->setConcat(m, *this);
|
||||
}
|
||||
|
||||
/**
|
||||
* A matrix is categorized as 'perspective' if the bottom row is not [0, 0, 0, 1].
|
||||
* For most uses, a bottom row of [0, 0, 0, X] behaves like a non-perspective matrix, though
|
||||
* it will be categorized as perspective. Calling normalizePerspective() will change the
|
||||
* matrix such that, if its bottom row was [0, 0, 0, X], it will be changed to [0, 0, 0, 1]
|
||||
* by scaling the rest of the matrix by 1/X.
|
||||
*
|
||||
* | A B C D | | A/X B/X C/X D/X |
|
||||
* | E F G H | -> | E/X F/X G/X H/X | for X != 0
|
||||
* | I J K L | | I/X J/X K/X L/X |
|
||||
* | 0 0 0 X | | 0 0 0 1 |
|
||||
*/
|
||||
void normalizePerspective();
|
||||
|
||||
/** Returns true if all elements of the matrix are finite. Returns false if any
|
||||
element is infinity, or NaN.
|
||||
|
||||
@return true if matrix has only finite elements
|
||||
*/
|
||||
bool isFinite() const { return SkIsFinite(fMat, 16); }
|
||||
|
||||
/** If this is invertible, return that in inverse and return true. If it is
|
||||
* not invertible, return false and leave the inverse parameter unchanged.
|
||||
*/
|
||||
[[nodiscard]] bool invert(SkM44* inverse) const;
|
||||
|
||||
[[nodiscard]] SkM44 transpose() const;
|
||||
|
||||
void dump() const;
|
||||
|
||||
////////////
|
||||
|
||||
SkV4 map(float x, float y, float z, float w) const;
|
||||
SkV4 operator*(const SkV4& v) const {
|
||||
return this->map(v.x, v.y, v.z, v.w);
|
||||
}
|
||||
SkV3 operator*(SkV3 v) const {
|
||||
auto v4 = this->map(v.x, v.y, v.z, 0);
|
||||
return {v4.x, v4.y, v4.z};
|
||||
}
|
||||
////////////////////// Converting to/from SkMatrix
|
||||
|
||||
/* When converting from SkM44 to SkMatrix, the third row and
|
||||
* column is dropped. When converting from SkMatrix to SkM44
|
||||
* the third row and column remain as identity:
|
||||
* [ a b c ] [ a b 0 c ]
|
||||
* [ d e f ] -> [ d e 0 f ]
|
||||
* [ g h i ] [ 0 0 1 0 ]
|
||||
* [ g h 0 i ]
|
||||
*/
|
||||
SkMatrix asM33() const {
|
||||
return SkMatrix::MakeAll(fMat[0], fMat[4], fMat[12],
|
||||
fMat[1], fMat[5], fMat[13],
|
||||
fMat[3], fMat[7], fMat[15]);
|
||||
}
|
||||
|
||||
explicit SkM44(const SkMatrix& src)
|
||||
: SkM44(src[SkMatrix::kMScaleX], src[SkMatrix::kMSkewX], 0, src[SkMatrix::kMTransX],
|
||||
src[SkMatrix::kMSkewY], src[SkMatrix::kMScaleY], 0, src[SkMatrix::kMTransY],
|
||||
0, 0, 1, 0,
|
||||
src[SkMatrix::kMPersp0], src[SkMatrix::kMPersp1], 0, src[SkMatrix::kMPersp2])
|
||||
{}
|
||||
|
||||
SkM44& preTranslate(SkScalar x, SkScalar y, SkScalar z = 0);
|
||||
SkM44& postTranslate(SkScalar x, SkScalar y, SkScalar z = 0);
|
||||
|
||||
SkM44& preScale(SkScalar x, SkScalar y);
|
||||
SkM44& preScale(SkScalar x, SkScalar y, SkScalar z);
|
||||
SkM44& preConcat(const SkMatrix&);
|
||||
|
||||
private:
|
||||
/* Stored in column-major.
|
||||
* Indices
|
||||
* 0 4 8 12 1 0 0 trans_x
|
||||
* 1 5 9 13 e.g. 0 1 0 trans_y
|
||||
* 2 6 10 14 0 0 1 trans_z
|
||||
* 3 7 11 15 0 0 0 1
|
||||
*/
|
||||
SkScalar fMat[16];
|
||||
|
||||
friend class SkMatrixPriv;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright 2008 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 SkMallocPixelRef_DEFINED
|
||||
#define SkMallocPixelRef_DEFINED
|
||||
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/core/SkTypes.h"
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
class SkData;
|
||||
class SkPixelRef;
|
||||
struct SkImageInfo;
|
||||
|
||||
/** We explicitly use the same allocator for our pixels that SkMask does,
|
||||
so that we can freely assign memory allocated by one class to the other.
|
||||
*/
|
||||
namespace SkMallocPixelRef {
|
||||
/**
|
||||
* Return a new SkMallocPixelRef, automatically allocating storage for the
|
||||
* pixels. If rowBytes are 0, an optimal value will be chosen automatically.
|
||||
* If rowBytes is > 0, then it will be respected, or NULL will be returned
|
||||
* if rowBytes is invalid for the specified info.
|
||||
*
|
||||
* All pixel bytes are zeroed.
|
||||
*
|
||||
* Returns NULL on failure.
|
||||
*/
|
||||
SK_API sk_sp<SkPixelRef> MakeAllocate(const SkImageInfo&, size_t rowBytes);
|
||||
|
||||
/**
|
||||
* Return a new SkMallocPixelRef that will use the provided SkData and
|
||||
* rowBytes as pixel storage. The SkData will be ref()ed and on
|
||||
* destruction of the PixelRef, the SkData will be unref()ed.
|
||||
*
|
||||
* Returns NULL on failure.
|
||||
*/
|
||||
SK_API sk_sp<SkPixelRef> MakeWithData(const SkImageInfo&, size_t rowBytes, sk_sp<SkData> data);
|
||||
} // namespace SkMallocPixelRef
|
||||
#endif
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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 SkMaskFilter_DEFINED
|
||||
#define SkMaskFilter_DEFINED
|
||||
|
||||
#include "include/core/SkFlattenable.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/core/SkScalar.h"
|
||||
#include "include/core/SkTypes.h"
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
enum SkBlurStyle : int;
|
||||
struct SkDeserialProcs;
|
||||
|
||||
/** \class SkMaskFilter
|
||||
|
||||
SkMaskFilter is the base class for object that perform transformations on
|
||||
the mask before drawing it. An example subclass is Blur.
|
||||
*/
|
||||
class SK_API SkMaskFilter : public SkFlattenable {
|
||||
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 respectCTM if true the blur's sigma is modified by the CTM.
|
||||
* @return The new blur maskfilter
|
||||
*/
|
||||
static sk_sp<SkMaskFilter> MakeBlur(SkBlurStyle style, SkScalar sigma,
|
||||
bool respectCTM = true);
|
||||
|
||||
static sk_sp<SkMaskFilter> Deserialize(const void* data, size_t size,
|
||||
const SkDeserialProcs* procs = nullptr);
|
||||
|
||||
private:
|
||||
static void RegisterFlattenables();
|
||||
friend class SkFlattenable;
|
||||
};
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,429 @@
|
|||
/*
|
||||
* Copyright 2021 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkMesh_DEFINED
|
||||
#define SkMesh_DEFINED
|
||||
|
||||
#include "include/core/SkData.h"
|
||||
#include "include/core/SkRect.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/core/SkSpan.h"
|
||||
#include "include/core/SkString.h"
|
||||
#include "include/effects/SkRuntimeEffect.h"
|
||||
#include "include/private/base/SkAPI.h"
|
||||
#include "include/private/base/SkTArray.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string_view>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
class GrDirectContext;
|
||||
class SkColorSpace;
|
||||
enum SkAlphaType : int;
|
||||
|
||||
namespace SkSL { struct Program; }
|
||||
|
||||
/**
|
||||
* A specification for custom meshes. Specifies the vertex buffer attributes and stride, the
|
||||
* vertex program that produces a user-defined set of varyings, and a fragment program that ingests
|
||||
* the interpolated varyings and produces local coordinates for shading and optionally a color.
|
||||
*
|
||||
* The varyings must include a float2 named "position". If the passed varyings does not
|
||||
* contain such a varying then one is implicitly added to the final specification and the SkSL
|
||||
* Varyings struct described below. It is an error to have a varying named "position" that has a
|
||||
* type other than float2.
|
||||
*
|
||||
* The provided attributes and varyings are used to create Attributes and Varyings structs in SkSL
|
||||
* that are used by the shaders. Each attribute from the Attribute span becomes a member of the
|
||||
* SkSL Attributes struct and likewise for the varyings.
|
||||
*
|
||||
* The signature of the vertex program must be:
|
||||
* Varyings main(const Attributes).
|
||||
*
|
||||
* The signature of the fragment program must be either:
|
||||
* float2 main(const Varyings)
|
||||
* or
|
||||
* float2 main(const Varyings, out (half4|float4) color)
|
||||
*
|
||||
* where the return value is the local coordinates that will be used to access SkShader. If the
|
||||
* color variant is used, the returned color will be blended with SkPaint's SkShader (or SkPaint
|
||||
* color in absence of a SkShader) using the SkBlender passed to SkCanvas drawMesh(). To use
|
||||
* interpolated local space positions as the shader coordinates, equivalent to how SkPaths are
|
||||
* shaded, return the position field from the Varying struct as the coordinates.
|
||||
*
|
||||
* The vertex and fragment programs may both contain uniforms. Uniforms with the same name are
|
||||
* assumed to be shared between stages. It is an error to specify uniforms in the vertex and
|
||||
* fragment program with the same name but different types, dimensionality, or layouts.
|
||||
*/
|
||||
class SK_API SkMeshSpecification : public SkNVRefCnt<SkMeshSpecification> {
|
||||
public:
|
||||
/** These values are enforced when creating a specification. */
|
||||
static constexpr size_t kMaxStride = 1024;
|
||||
static constexpr size_t kMaxAttributes = 8;
|
||||
static constexpr size_t kStrideAlignment = 4;
|
||||
static constexpr size_t kOffsetAlignment = 4;
|
||||
static constexpr size_t kMaxVaryings = 6;
|
||||
|
||||
struct Attribute {
|
||||
enum class Type : uint32_t { // CPU representation Shader Type
|
||||
kFloat, // float float
|
||||
kFloat2, // two floats float2
|
||||
kFloat3, // three floats float3
|
||||
kFloat4, // four floats float4
|
||||
kUByte4_unorm, // four bytes half4
|
||||
|
||||
kLast = kUByte4_unorm
|
||||
};
|
||||
Type type;
|
||||
size_t offset;
|
||||
SkString name;
|
||||
};
|
||||
|
||||
struct Varying {
|
||||
enum class Type : uint32_t {
|
||||
kFloat, // "float"
|
||||
kFloat2, // "float2"
|
||||
kFloat3, // "float3"
|
||||
kFloat4, // "float4"
|
||||
kHalf, // "half"
|
||||
kHalf2, // "half2"
|
||||
kHalf3, // "half3"
|
||||
kHalf4, // "half4"
|
||||
|
||||
kLast = kHalf4
|
||||
};
|
||||
Type type;
|
||||
SkString name;
|
||||
};
|
||||
|
||||
using Uniform = SkRuntimeEffect::Uniform;
|
||||
using Child = SkRuntimeEffect::Child;
|
||||
|
||||
~SkMeshSpecification();
|
||||
|
||||
struct Result {
|
||||
sk_sp<SkMeshSpecification> specification;
|
||||
SkString error;
|
||||
};
|
||||
|
||||
/**
|
||||
* If successful the return is a specification and an empty error string. Otherwise, it is a
|
||||
* null specification a non-empty error string.
|
||||
*
|
||||
* @param attributes The vertex attributes that will be consumed by 'vs'. Attributes need
|
||||
* not be tightly packed but attribute offsets must be aligned to
|
||||
* kOffsetAlignment and offset + size may not be greater than
|
||||
* 'vertexStride'. At least one attribute is required.
|
||||
* @param vertexStride The offset between successive attribute values. This must be aligned to
|
||||
* kStrideAlignment.
|
||||
* @param varyings The varyings that will be written by 'vs' and read by 'fs'. This may
|
||||
* be empty.
|
||||
* @param vs The vertex shader code that computes a vertex position and the varyings
|
||||
* from the attributes.
|
||||
* @param fs The fragment code that computes a local coordinate and optionally a
|
||||
* color from the varyings. The local coordinate is used to sample
|
||||
* SkShader.
|
||||
* @param cs The colorspace of the color produced by 'fs'. Ignored if 'fs's main()
|
||||
* function does not have a color out param.
|
||||
* @param at The alpha type of the color produced by 'fs'. Ignored if 'fs's main()
|
||||
* function does not have a color out param. Cannot be kUnknown.
|
||||
*/
|
||||
static Result Make(SkSpan<const Attribute> attributes,
|
||||
size_t vertexStride,
|
||||
SkSpan<const Varying> varyings,
|
||||
const SkString& vs,
|
||||
const SkString& fs);
|
||||
static Result Make(SkSpan<const Attribute> attributes,
|
||||
size_t vertexStride,
|
||||
SkSpan<const Varying> varyings,
|
||||
const SkString& vs,
|
||||
const SkString& fs,
|
||||
sk_sp<SkColorSpace> cs);
|
||||
static Result Make(SkSpan<const Attribute> attributes,
|
||||
size_t vertexStride,
|
||||
SkSpan<const Varying> varyings,
|
||||
const SkString& vs,
|
||||
const SkString& fs,
|
||||
sk_sp<SkColorSpace> cs,
|
||||
SkAlphaType at);
|
||||
|
||||
SkSpan<const Attribute> attributes() const { return SkSpan(fAttributes); }
|
||||
|
||||
/**
|
||||
* Combined size of all 'uniform' variables. When creating a SkMesh with this specification
|
||||
* provide an SkData of this size, containing values for all of those variables. Use uniforms()
|
||||
* to get the offset of each uniform within the SkData.
|
||||
*/
|
||||
size_t uniformSize() const;
|
||||
|
||||
/**
|
||||
* Provides info about individual uniforms including the offset into an SkData where each
|
||||
* uniform value should be placed.
|
||||
*/
|
||||
SkSpan<const Uniform> uniforms() const { return SkSpan(fUniforms); }
|
||||
|
||||
/** Provides basic info about individual children: names, indices and runtime effect type. */
|
||||
SkSpan<const Child> children() const { return SkSpan(fChildren); }
|
||||
|
||||
/** Returns a pointer to the named child's description, or nullptr if not found. */
|
||||
const Child* findChild(std::string_view name) const;
|
||||
|
||||
/** Returns a pointer to the named uniform variable's description, or nullptr if not found. */
|
||||
const Uniform* findUniform(std::string_view name) const;
|
||||
|
||||
/** Returns a pointer to the named attribute, or nullptr if not found. */
|
||||
const Attribute* findAttribute(std::string_view name) const;
|
||||
|
||||
/** Returns a pointer to the named varying, or nullptr if not found. */
|
||||
const Varying* findVarying(std::string_view name) const;
|
||||
|
||||
size_t stride() const { return fStride; }
|
||||
|
||||
SkColorSpace* colorSpace() const { return fColorSpace.get(); }
|
||||
|
||||
private:
|
||||
friend struct SkMeshSpecificationPriv;
|
||||
|
||||
enum class ColorType {
|
||||
kNone,
|
||||
kHalf4,
|
||||
kFloat4,
|
||||
};
|
||||
|
||||
static Result MakeFromSourceWithStructs(SkSpan<const Attribute> attributes,
|
||||
size_t stride,
|
||||
SkSpan<const Varying> varyings,
|
||||
const SkString& vs,
|
||||
const SkString& fs,
|
||||
sk_sp<SkColorSpace> cs,
|
||||
SkAlphaType at);
|
||||
|
||||
SkMeshSpecification(SkSpan<const Attribute>,
|
||||
size_t,
|
||||
SkSpan<const Varying>,
|
||||
int passthroughLocalCoordsVaryingIndex,
|
||||
uint32_t deadVaryingMask,
|
||||
std::vector<Uniform> uniforms,
|
||||
std::vector<Child> children,
|
||||
std::unique_ptr<const SkSL::Program>,
|
||||
std::unique_ptr<const SkSL::Program>,
|
||||
ColorType,
|
||||
sk_sp<SkColorSpace>,
|
||||
SkAlphaType);
|
||||
|
||||
SkMeshSpecification(const SkMeshSpecification&) = delete;
|
||||
SkMeshSpecification(SkMeshSpecification&&) = delete;
|
||||
|
||||
SkMeshSpecification& operator=(const SkMeshSpecification&) = delete;
|
||||
SkMeshSpecification& operator=(SkMeshSpecification&&) = delete;
|
||||
|
||||
const std::vector<Attribute> fAttributes;
|
||||
const std::vector<Varying> fVaryings;
|
||||
const std::vector<Uniform> fUniforms;
|
||||
const std::vector<Child> fChildren;
|
||||
const std::unique_ptr<const SkSL::Program> fVS;
|
||||
const std::unique_ptr<const SkSL::Program> fFS;
|
||||
const size_t fStride;
|
||||
uint32_t fHash;
|
||||
const int fPassthroughLocalCoordsVaryingIndex;
|
||||
const uint32_t fDeadVaryingMask;
|
||||
const ColorType fColorType;
|
||||
const sk_sp<SkColorSpace> fColorSpace;
|
||||
const SkAlphaType fAlphaType;
|
||||
};
|
||||
|
||||
/**
|
||||
* A vertex buffer, a topology, optionally an index buffer, and a compatible SkMeshSpecification.
|
||||
*
|
||||
* The data in the vertex buffer is expected to contain the attributes described by the spec
|
||||
* for vertexCount vertices, beginning at vertexOffset. vertexOffset must be aligned to the
|
||||
* SkMeshSpecification's vertex stride. The size of the buffer must be at least vertexOffset +
|
||||
* spec->stride()*vertexCount (even if vertex attributes contains pad at the end of the stride). If
|
||||
* the specified bounds do not contain all the points output by the spec's vertex program when
|
||||
* applied to the vertices in the custom mesh, then the result is undefined.
|
||||
*
|
||||
* MakeIndexed may be used to create an indexed mesh. indexCount indices are read from the index
|
||||
* buffer at the specified offset, which must be aligned to 2. The indices are always unsigned
|
||||
* 16-bit integers. The index count must be at least 3.
|
||||
*
|
||||
* If Make() is used, the implicit index sequence is 0, 1, 2, 3, ... and vertexCount must be at
|
||||
* least 3.
|
||||
*
|
||||
* Both Make() and MakeIndexed() take a SkData with the uniform values. See
|
||||
* SkMeshSpecification::uniformSize() and SkMeshSpecification::uniforms() for sizing and packing
|
||||
* uniforms into the SkData.
|
||||
*/
|
||||
class SK_API SkMesh {
|
||||
public:
|
||||
class IndexBuffer : public SkRefCnt {
|
||||
public:
|
||||
virtual size_t size() const = 0;
|
||||
|
||||
/**
|
||||
* Modifies the data in the IndexBuffer by copying size bytes from data into the buffer
|
||||
* at offset. Fails if offset + size > this->size() or if either offset or size is not
|
||||
* aligned to 4 bytes. The GrDirectContext* must match that used to create the buffer. We
|
||||
* take it as a parameter to emphasize that the context must be used to update the data and
|
||||
* thus the context must be valid for the current thread.
|
||||
*/
|
||||
bool update(GrDirectContext*, const void* data, size_t offset, size_t size);
|
||||
|
||||
private:
|
||||
virtual bool onUpdate(GrDirectContext*, const void* data, size_t offset, size_t size) = 0;
|
||||
};
|
||||
|
||||
class VertexBuffer : public SkRefCnt {
|
||||
public:
|
||||
virtual size_t size() const = 0;
|
||||
|
||||
/**
|
||||
* Modifies the data in the IndexBuffer by copying size bytes from data into the buffer
|
||||
* at offset. Fails if offset + size > this->size() or if either offset or size is not
|
||||
* aligned to 4 bytes. The GrDirectContext* must match that used to create the buffer. We
|
||||
* take it as a parameter to emphasize that the context must be used to update the data and
|
||||
* thus the context must be valid for the current thread.
|
||||
*/
|
||||
bool update(GrDirectContext*, const void* data, size_t offset, size_t size);
|
||||
|
||||
private:
|
||||
virtual bool onUpdate(GrDirectContext*, const void* data, size_t offset, size_t size) = 0;
|
||||
};
|
||||
|
||||
SkMesh();
|
||||
~SkMesh();
|
||||
|
||||
SkMesh(const SkMesh&);
|
||||
SkMesh(SkMesh&&);
|
||||
|
||||
SkMesh& operator=(const SkMesh&);
|
||||
SkMesh& operator=(SkMesh&&);
|
||||
|
||||
enum class Mode { kTriangles, kTriangleStrip };
|
||||
|
||||
struct Result;
|
||||
|
||||
using ChildPtr = SkRuntimeEffect::ChildPtr;
|
||||
|
||||
/**
|
||||
* Creates a non-indexed SkMesh. The returned SkMesh can be tested for validity using
|
||||
* SkMesh::isValid(). An invalid mesh simply fails to draws if passed to SkCanvas::drawMesh().
|
||||
* If the mesh is invalid the returned string give contain the reason for the failure (e.g. the
|
||||
* vertex buffer was null or uniform data too small).
|
||||
*/
|
||||
static Result Make(sk_sp<SkMeshSpecification>,
|
||||
Mode,
|
||||
sk_sp<VertexBuffer>,
|
||||
size_t vertexCount,
|
||||
size_t vertexOffset,
|
||||
sk_sp<const SkData> uniforms,
|
||||
SkSpan<ChildPtr> children,
|
||||
const SkRect& bounds);
|
||||
|
||||
/**
|
||||
* Creates an indexed SkMesh. The returned SkMesh can be tested for validity using
|
||||
* SkMesh::isValid(). A invalid mesh simply fails to draw if passed to SkCanvas::drawMesh().
|
||||
* If the mesh is invalid the returned string give contain the reason for the failure (e.g. the
|
||||
* index buffer was null or uniform data too small).
|
||||
*/
|
||||
static Result MakeIndexed(sk_sp<SkMeshSpecification>,
|
||||
Mode,
|
||||
sk_sp<VertexBuffer>,
|
||||
size_t vertexCount,
|
||||
size_t vertexOffset,
|
||||
sk_sp<IndexBuffer>,
|
||||
size_t indexCount,
|
||||
size_t indexOffset,
|
||||
sk_sp<const SkData> uniforms,
|
||||
SkSpan<ChildPtr> children,
|
||||
const SkRect& bounds);
|
||||
|
||||
sk_sp<SkMeshSpecification> refSpec() const { return fSpec; }
|
||||
SkMeshSpecification* spec() const { return fSpec.get(); }
|
||||
|
||||
Mode mode() const { return fMode; }
|
||||
|
||||
sk_sp<VertexBuffer> refVertexBuffer() const { return fVB; }
|
||||
VertexBuffer* vertexBuffer() const { return fVB.get(); }
|
||||
|
||||
size_t vertexOffset() const { return fVOffset; }
|
||||
size_t vertexCount() const { return fVCount; }
|
||||
|
||||
sk_sp<IndexBuffer> refIndexBuffer() const { return fIB; }
|
||||
IndexBuffer* indexBuffer() const { return fIB.get(); }
|
||||
|
||||
size_t indexOffset() const { return fIOffset; }
|
||||
size_t indexCount() const { return fICount; }
|
||||
|
||||
sk_sp<const SkData> refUniforms() const { return fUniforms; }
|
||||
const SkData* uniforms() const { return fUniforms.get(); }
|
||||
|
||||
SkSpan<const ChildPtr> children() const { return SkSpan(fChildren); }
|
||||
|
||||
SkRect bounds() const { return fBounds; }
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
private:
|
||||
std::tuple<bool, SkString> validate() const;
|
||||
|
||||
sk_sp<SkMeshSpecification> fSpec;
|
||||
|
||||
sk_sp<VertexBuffer> fVB;
|
||||
sk_sp<IndexBuffer> fIB;
|
||||
|
||||
sk_sp<const SkData> fUniforms;
|
||||
skia_private::STArray<2, ChildPtr> fChildren;
|
||||
|
||||
size_t fVOffset = 0; // Must be a multiple of spec->stride()
|
||||
size_t fVCount = 0;
|
||||
|
||||
size_t fIOffset = 0; // Must be a multiple of sizeof(uint16_t)
|
||||
size_t fICount = 0;
|
||||
|
||||
Mode fMode = Mode::kTriangles;
|
||||
|
||||
SkRect fBounds = SkRect::MakeEmpty();
|
||||
};
|
||||
|
||||
struct SkMesh::Result { SkMesh mesh; SkString error; };
|
||||
|
||||
namespace SkMeshes {
|
||||
/**
|
||||
* Makes a CPU-backed index buffer to be used with SkMeshes.
|
||||
*
|
||||
* @param data The data used to populate the buffer, or nullptr to create a zero-
|
||||
* initialized buffer.
|
||||
* @param size Both the size of the data in 'data' and the size of the resulting
|
||||
* buffer, in bytes.
|
||||
*/
|
||||
SK_API sk_sp<SkMesh::IndexBuffer> MakeIndexBuffer(const void* data, size_t size);
|
||||
|
||||
/**
|
||||
* Makes a copy of an index buffer. The copy will be CPU-backed.
|
||||
*/
|
||||
SK_API sk_sp<SkMesh::IndexBuffer> CopyIndexBuffer(const sk_sp<SkMesh::IndexBuffer>&);
|
||||
|
||||
/**
|
||||
* Makes a CPU-backed vertex buffer to be used with SkMeshes.
|
||||
*
|
||||
* @param data The data used to populate the buffer, or nullptr to create a zero-
|
||||
* initialized buffer.
|
||||
* @param size Both the size of the data in 'data' and the size of the resulting
|
||||
* buffer, in bytes.
|
||||
*/
|
||||
SK_API sk_sp<SkMesh::VertexBuffer> MakeVertexBuffer(const void*, size_t size);
|
||||
|
||||
/**
|
||||
* Makes a copy of a vertex buffer. The copy will be CPU-backed.
|
||||
*/
|
||||
SK_API sk_sp<SkMesh::VertexBuffer> CopyVertexBuffer(const sk_sp<SkMesh::VertexBuffer>&);
|
||||
} // namespace SkMeshes
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* 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 SK_MILESTONE
|
||||
#define SK_MILESTONE 150
|
||||
#endif
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright 2022 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkOpenTypeSVGDecoder_DEFINED
|
||||
#define SkOpenTypeSVGDecoder_DEFINED
|
||||
|
||||
#include "include/core/SkColor.h"
|
||||
#include "include/core/SkSpan.h"
|
||||
#include "include/core/SkTypes.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
class SkCanvas;
|
||||
|
||||
class SkOpenTypeSVGDecoder {
|
||||
public:
|
||||
/** Each instance probably owns an SVG DOM.
|
||||
* The instance may be cached so needs to report how much memory it retains.
|
||||
*/
|
||||
virtual size_t approximateSize() = 0;
|
||||
virtual bool render(SkCanvas&, int upem, SkGlyphID glyphId,
|
||||
SkColor foregroundColor, SkSpan<SkColor> palette) = 0;
|
||||
virtual ~SkOpenTypeSVGDecoder() = default;
|
||||
};
|
||||
|
||||
#endif // SkOpenTypeSVGDecoder_DEFINED
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* 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 SkOverdrawCanvas_DEFINED
|
||||
#define SkOverdrawCanvas_DEFINED
|
||||
|
||||
#include "include/core/SkCanvas.h"
|
||||
#include "include/core/SkCanvasVirtualEnforcer.h"
|
||||
#include "include/core/SkColor.h"
|
||||
#include "include/core/SkPaint.h"
|
||||
#include "include/core/SkSamplingOptions.h"
|
||||
#include "include/core/SkScalar.h"
|
||||
#include "include/private/base/SkAPI.h"
|
||||
#include "include/utils/SkNWayCanvas.h"
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
class SkData;
|
||||
class SkDrawable;
|
||||
class SkImage;
|
||||
class SkMatrix;
|
||||
class SkPath;
|
||||
class SkPicture;
|
||||
class SkRRect;
|
||||
class SkRegion;
|
||||
class SkTextBlob;
|
||||
class SkVertices;
|
||||
enum class SkBlendMode;
|
||||
namespace sktext { class GlyphRunList; }
|
||||
struct SkDrawShadowRec;
|
||||
struct SkPoint;
|
||||
struct SkRSXform;
|
||||
struct SkRect;
|
||||
|
||||
/**
|
||||
* Captures all drawing commands. Rather than draw the actual content, this device
|
||||
* increments the alpha channel of each pixel every time it would have been touched
|
||||
* by a draw call. This is useful for detecting overdraw.
|
||||
*/
|
||||
class SK_API SkOverdrawCanvas : public SkCanvasVirtualEnforcer<SkNWayCanvas> {
|
||||
public:
|
||||
/* Does not take ownership of canvas */
|
||||
explicit SkOverdrawCanvas(SkCanvas*);
|
||||
|
||||
void onDrawTextBlob(const SkTextBlob*, SkScalar, SkScalar, const SkPaint&) override;
|
||||
void onDrawGlyphRunList(
|
||||
const sktext::GlyphRunList& glyphRunList, const SkPaint& paint) override;
|
||||
void onDrawPatch(const SkPoint[12], const SkColor[4], const SkPoint[4], SkBlendMode,
|
||||
const SkPaint&) override;
|
||||
void onDrawPaint(const SkPaint&) override;
|
||||
void onDrawBehind(const SkPaint& paint) override;
|
||||
void onDrawRect(const SkRect&, const SkPaint&) override;
|
||||
void onDrawRegion(const SkRegion&, const SkPaint&) override;
|
||||
void onDrawOval(const SkRect&, const SkPaint&) override;
|
||||
void onDrawArc(const SkRect&, SkScalar, SkScalar, bool, const SkPaint&) override;
|
||||
void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override;
|
||||
void onDrawRRect(const SkRRect&, const SkPaint&) override;
|
||||
void onDrawPoints(PointMode, size_t, const SkPoint[], const SkPaint&) override;
|
||||
void onDrawVerticesObject(const SkVertices*, SkBlendMode, const SkPaint&) override;
|
||||
void onDrawPath(const SkPath&, const SkPaint&) override;
|
||||
|
||||
void onDrawImage2(const SkImage*, SkScalar, SkScalar, const SkSamplingOptions&,
|
||||
const SkPaint*) override;
|
||||
void onDrawImageRect2(const SkImage*, const SkRect&, const SkRect&, const SkSamplingOptions&,
|
||||
const SkPaint*, SrcRectConstraint) override;
|
||||
void onDrawImageLattice2(const SkImage*, const Lattice&, const SkRect&, SkFilterMode,
|
||||
const SkPaint*) override;
|
||||
void onDrawAtlas2(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], int,
|
||||
SkBlendMode, const SkSamplingOptions&, const SkRect*, const SkPaint*) override;
|
||||
|
||||
void onDrawDrawable(SkDrawable*, const SkMatrix*) override;
|
||||
void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) override;
|
||||
|
||||
void onDrawAnnotation(const SkRect&, const char key[], SkData* value) override;
|
||||
void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&) override;
|
||||
|
||||
void onDrawEdgeAAQuad(const SkRect&, const SkPoint[4], SkCanvas::QuadAAFlags, const SkColor4f&,
|
||||
SkBlendMode) override;
|
||||
void onDrawEdgeAAImageSet2(const ImageSetEntry[], int count, const SkPoint[], const SkMatrix[],
|
||||
const SkSamplingOptions&,const SkPaint*, SrcRectConstraint) override;
|
||||
|
||||
private:
|
||||
inline SkPaint overdrawPaint(const SkPaint& paint);
|
||||
|
||||
SkPaint fPaint;
|
||||
|
||||
using INHERITED = SkCanvasVirtualEnforcer<SkNWayCanvas>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,698 @@
|
|||
/*
|
||||
* 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 SkPaint_DEFINED
|
||||
#define SkPaint_DEFINED
|
||||
|
||||
#include "include/core/SkColor.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/core/SkScalar.h"
|
||||
#include "include/core/SkTypes.h"
|
||||
#include "include/private/base/SkCPUTypes.h"
|
||||
#include "include/private/base/SkFloatingPoint.h"
|
||||
#include "include/private/base/SkTo.h"
|
||||
#include "include/private/base/SkTypeTraits.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
|
||||
class SkBlender;
|
||||
class SkColorFilter;
|
||||
class SkColorSpace;
|
||||
class SkImageFilter;
|
||||
class SkMaskFilter;
|
||||
class SkPathEffect;
|
||||
class SkShader;
|
||||
enum class SkBlendMode;
|
||||
struct SkRect;
|
||||
|
||||
/** \class SkPaint
|
||||
SkPaint controls options applied when drawing. SkPaint collects all
|
||||
options outside of the SkCanvas clip and SkCanvas matrix.
|
||||
|
||||
Various options apply to strokes and fills, and images.
|
||||
|
||||
SkPaint collects effects and filters that describe single-pass and multiple-pass
|
||||
algorithms that alter the drawing geometry, color, and transparency. For instance,
|
||||
SkPaint does not directly implement dashing or blur, but contains the objects that do so.
|
||||
*/
|
||||
class SK_API SkPaint {
|
||||
public:
|
||||
|
||||
/** Constructs SkPaint with default values.
|
||||
|
||||
@return default initialized SkPaint
|
||||
|
||||
example: https://fiddle.skia.org/c/@Paint_empty_constructor
|
||||
*/
|
||||
SkPaint();
|
||||
|
||||
/** Constructs SkPaint with default values and the given color.
|
||||
|
||||
Sets alpha and RGB used when stroking and filling. The color is four floating
|
||||
point values, unpremultiplied. The color values are interpreted as being in
|
||||
the colorSpace. If colorSpace is nullptr, then color is assumed to be in the
|
||||
sRGB color space.
|
||||
|
||||
@param color unpremultiplied RGBA
|
||||
@param colorSpace SkColorSpace describing the encoding of color
|
||||
@return SkPaint with the given color
|
||||
*/
|
||||
explicit SkPaint(const SkColor4f& color, SkColorSpace* colorSpace = nullptr);
|
||||
|
||||
/** Makes a shallow copy of SkPaint. SkPathEffect, SkShader,
|
||||
SkMaskFilter, SkColorFilter, and SkImageFilter are shared
|
||||
between the original paint and the copy. Objects containing SkRefCnt increment
|
||||
their references by one.
|
||||
|
||||
The referenced objects SkPathEffect, SkShader, SkMaskFilter, SkColorFilter,
|
||||
and SkImageFilter cannot be modified after they are created.
|
||||
This prevents objects with SkRefCnt from being modified once SkPaint refers to them.
|
||||
|
||||
@param paint original to copy
|
||||
@return shallow copy of paint
|
||||
|
||||
example: https://fiddle.skia.org/c/@Paint_copy_const_SkPaint
|
||||
*/
|
||||
SkPaint(const SkPaint& paint);
|
||||
|
||||
/** Implements a move constructor to avoid increasing the reference counts
|
||||
of objects referenced by the paint.
|
||||
|
||||
After the call, paint is undefined, and can be safely destructed.
|
||||
|
||||
@param paint original to move
|
||||
@return content of paint
|
||||
|
||||
example: https://fiddle.skia.org/c/@Paint_move_SkPaint
|
||||
*/
|
||||
SkPaint(SkPaint&& paint);
|
||||
|
||||
/** Decreases SkPaint SkRefCnt of owned objects: SkPathEffect, SkShader,
|
||||
SkMaskFilter, SkColorFilter, and SkImageFilter. If the
|
||||
objects containing SkRefCnt go to zero, they are deleted.
|
||||
*/
|
||||
~SkPaint();
|
||||
|
||||
/** Makes a shallow copy of SkPaint. SkPathEffect, SkShader,
|
||||
SkMaskFilter, SkColorFilter, and SkImageFilter are shared
|
||||
between the original paint and the copy. Objects containing SkRefCnt in the
|
||||
prior destination are decreased by one, and the referenced objects are deleted if the
|
||||
resulting count is zero. Objects containing SkRefCnt in the parameter paint
|
||||
are increased by one. paint is unmodified.
|
||||
|
||||
@param paint original to copy
|
||||
@return content of paint
|
||||
|
||||
example: https://fiddle.skia.org/c/@Paint_copy_operator
|
||||
*/
|
||||
SkPaint& operator=(const SkPaint& paint);
|
||||
|
||||
/** Moves the paint to avoid increasing the reference counts
|
||||
of objects referenced by the paint parameter. Objects containing SkRefCnt in the
|
||||
prior destination are decreased by one; those objects are deleted if the resulting count
|
||||
is zero.
|
||||
|
||||
After the call, paint is undefined, and can be safely destructed.
|
||||
|
||||
@param paint original to move
|
||||
@return content of paint
|
||||
|
||||
example: https://fiddle.skia.org/c/@Paint_move_operator
|
||||
*/
|
||||
SkPaint& operator=(SkPaint&& paint);
|
||||
|
||||
/** Compares a and b, and returns true if a and b are equivalent. May return false
|
||||
if SkPathEffect, SkShader, SkMaskFilter, SkColorFilter,
|
||||
or SkImageFilter have identical contents but different pointers.
|
||||
|
||||
@param a SkPaint to compare
|
||||
@param b SkPaint to compare
|
||||
@return true if SkPaint pair are equivalent
|
||||
*/
|
||||
SK_API friend bool operator==(const SkPaint& a, const SkPaint& b);
|
||||
|
||||
/** Compares a and b, and returns true if a and b are not equivalent. May return true
|
||||
if SkPathEffect, SkShader, SkMaskFilter, SkColorFilter,
|
||||
or SkImageFilter have identical contents but different pointers.
|
||||
|
||||
@param a SkPaint to compare
|
||||
@param b SkPaint to compare
|
||||
@return true if SkPaint pair are not equivalent
|
||||
*/
|
||||
friend bool operator!=(const SkPaint& a, const SkPaint& b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
/** Sets all SkPaint contents to their initial values. This is equivalent to replacing
|
||||
SkPaint with the result of SkPaint().
|
||||
|
||||
example: https://fiddle.skia.org/c/@Paint_reset
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/** Returns true if pixels on the active edges of SkPath may be drawn with partial transparency.
|
||||
@return antialiasing state
|
||||
*/
|
||||
bool isAntiAlias() const {
|
||||
return SkToBool(fBitfields.fAntiAlias);
|
||||
}
|
||||
|
||||
/** Requests, but does not require, that edge pixels draw opaque or with
|
||||
partial transparency.
|
||||
@param aa setting for antialiasing
|
||||
*/
|
||||
void setAntiAlias(bool aa) { fBitfields.fAntiAlias = static_cast<unsigned>(aa); }
|
||||
|
||||
/** Returns true if color error may be distributed to smooth color transition.
|
||||
@return dithering state
|
||||
*/
|
||||
bool isDither() const {
|
||||
return SkToBool(fBitfields.fDither);
|
||||
}
|
||||
|
||||
/** Requests, but does not require, to distribute color error.
|
||||
@param dither setting for dithering
|
||||
*/
|
||||
void setDither(bool dither) { fBitfields.fDither = static_cast<unsigned>(dither); }
|
||||
|
||||
/** \enum SkPaint::Style
|
||||
Set Style to fill, stroke, or both fill and stroke geometry.
|
||||
The stroke and fill
|
||||
share all paint attributes; for instance, they are drawn with the same color.
|
||||
|
||||
Use kStrokeAndFill_Style to avoid hitting the same pixels twice with a stroke draw and
|
||||
a fill draw.
|
||||
*/
|
||||
enum Style : uint8_t {
|
||||
kFill_Style, //!< set to fill geometry
|
||||
kStroke_Style, //!< set to stroke geometry
|
||||
kStrokeAndFill_Style, //!< sets to stroke and fill geometry
|
||||
};
|
||||
|
||||
/** May be used to verify that SkPaint::Style is a legal value.
|
||||
*/
|
||||
static constexpr int kStyleCount = kStrokeAndFill_Style + 1;
|
||||
|
||||
/** Returns whether the geometry is filled, stroked, or filled and stroked.
|
||||
*/
|
||||
Style getStyle() const { return (Style)fBitfields.fStyle; }
|
||||
|
||||
/** Sets whether the geometry is filled, stroked, or filled and stroked.
|
||||
Has no effect if style is not a legal SkPaint::Style value.
|
||||
|
||||
example: https://fiddle.skia.org/c/@Paint_setStyle
|
||||
example: https://fiddle.skia.org/c/@Stroke_Width
|
||||
*/
|
||||
void setStyle(Style style);
|
||||
|
||||
/**
|
||||
* Set paint's style to kStroke if true, or kFill if false.
|
||||
*/
|
||||
void setStroke(bool);
|
||||
|
||||
/** Retrieves alpha and RGB, unpremultiplied, packed into 32 bits.
|
||||
Use helpers SkColorGetA(), SkColorGetR(), SkColorGetG(), and SkColorGetB() to extract
|
||||
a color component.
|
||||
|
||||
@return unpremultiplied ARGB
|
||||
*/
|
||||
SkColor getColor() const { return fColor4f.toSkColor(); }
|
||||
|
||||
/** Retrieves alpha and RGB, unpremultiplied, as four floating point values. RGB are
|
||||
extended sRGB values (sRGB gamut, and encoded with the sRGB transfer function).
|
||||
|
||||
@return unpremultiplied RGBA
|
||||
*/
|
||||
SkColor4f getColor4f() const { return fColor4f; }
|
||||
|
||||
/** Sets alpha and RGB used when stroking and filling. The color is a 32-bit value,
|
||||
unpremultiplied, packing 8-bit components for alpha, red, blue, and green.
|
||||
|
||||
@param color unpremultiplied ARGB
|
||||
|
||||
example: https://fiddle.skia.org/c/@Paint_setColor
|
||||
*/
|
||||
void setColor(SkColor color);
|
||||
|
||||
/** Sets alpha and RGB used when stroking and filling. The color is four floating
|
||||
point values, unpremultiplied. The color values are interpreted as being in
|
||||
the colorSpace. If colorSpace is nullptr, then color is assumed to be in the
|
||||
sRGB color space.
|
||||
|
||||
@param color unpremultiplied RGBA
|
||||
@param colorSpace SkColorSpace describing the encoding of color
|
||||
*/
|
||||
void setColor(const SkColor4f& color, SkColorSpace* colorSpace = nullptr);
|
||||
|
||||
void setColor4f(const SkColor4f& color, SkColorSpace* colorSpace = nullptr) {
|
||||
this->setColor(color, colorSpace);
|
||||
}
|
||||
|
||||
/** Retrieves alpha from the color used when stroking and filling.
|
||||
|
||||
@return alpha ranging from zero, fully transparent, to one, fully opaque
|
||||
*/
|
||||
float getAlphaf() const { return fColor4f.fA; }
|
||||
|
||||
// Helper that scales the alpha by 255.
|
||||
uint8_t getAlpha() const {
|
||||
return static_cast<uint8_t>(sk_float_round2int(this->getAlphaf() * 255));
|
||||
}
|
||||
|
||||
/** Replaces alpha, leaving RGB
|
||||
unchanged. An out of range value triggers an assert in the debug
|
||||
build. a is a value from 0.0 to 1.0.
|
||||
a set to zero makes color fully transparent; a set to 1.0 makes color
|
||||
fully opaque.
|
||||
|
||||
@param a alpha component of color
|
||||
*/
|
||||
void setAlphaf(float a);
|
||||
|
||||
// Helper that accepts an int between 0 and 255, and divides it by 255.0
|
||||
void setAlpha(U8CPU a) {
|
||||
this->setAlphaf(a * (1.0f / 255));
|
||||
}
|
||||
|
||||
/** Sets color used when drawing solid fills. The color components range from 0 to 255.
|
||||
The color is unpremultiplied; alpha sets the transparency independent of RGB.
|
||||
|
||||
@param a amount of alpha, from fully transparent (0) to fully opaque (255)
|
||||
@param r amount of red, from no red (0) to full red (255)
|
||||
@param g amount of green, from no green (0) to full green (255)
|
||||
@param b amount of blue, from no blue (0) to full blue (255)
|
||||
|
||||
example: https://fiddle.skia.org/c/@Paint_setARGB
|
||||
*/
|
||||
void setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b);
|
||||
|
||||
/** Returns the thickness of the pen used by SkPaint to
|
||||
outline the shape.
|
||||
|
||||
@return zero for hairline, greater than zero for pen thickness
|
||||
*/
|
||||
SkScalar getStrokeWidth() const { return fWidth; }
|
||||
|
||||
/** Sets the thickness of the pen used by the paint to outline the shape.
|
||||
A stroke-width of zero is treated as "hairline" width. Hairlines are always exactly one
|
||||
pixel wide in device space (their thickness does not change as the canvas is scaled).
|
||||
Negative stroke-widths are invalid; setting a negative width will have no effect.
|
||||
|
||||
@param width zero thickness for hairline; greater than zero for pen thickness
|
||||
|
||||
example: https://fiddle.skia.org/c/@Miter_Limit
|
||||
example: https://fiddle.skia.org/c/@Paint_setStrokeWidth
|
||||
*/
|
||||
void setStrokeWidth(SkScalar width);
|
||||
|
||||
/** Returns the limit at which a sharp corner is drawn beveled.
|
||||
|
||||
@return zero and greater miter limit
|
||||
*/
|
||||
SkScalar getStrokeMiter() const { return fMiterLimit; }
|
||||
|
||||
/** When stroking a small joinAngle with miter, the miterLength may be very long.
|
||||
When miterLength > maxMiterLength (or joinAngle < minJoinAngle) the join will become bevel.
|
||||
miterLimit = maxMiterLength / strokeWidth or miterLimit = 1 / sin(minJoinAngle / 2).
|
||||
|
||||
This call has no effect if the miterLimit passed is less than zero.
|
||||
Values less than one will be treated as bevel.
|
||||
|
||||
@param miterLimit zero and greater miter limit
|
||||
|
||||
example: https://fiddle.skia.org/c/@Paint_setStrokeMiter
|
||||
*/
|
||||
void setStrokeMiter(SkScalar miterLimit);
|
||||
|
||||
/** \enum SkPaint::Cap
|
||||
Cap draws at the beginning and end of an open path contour.
|
||||
*/
|
||||
enum Cap {
|
||||
kButt_Cap, //!< no stroke extension
|
||||
kRound_Cap, //!< adds circle
|
||||
kSquare_Cap, //!< adds square
|
||||
kLast_Cap = kSquare_Cap, //!< largest Cap value
|
||||
kDefault_Cap = kButt_Cap, //!< equivalent to kButt_Cap
|
||||
};
|
||||
|
||||
/** May be used to verify that SkPaint::Cap is a legal value.
|
||||
*/
|
||||
static constexpr int kCapCount = kLast_Cap + 1;
|
||||
|
||||
/** \enum SkPaint::Join
|
||||
Join specifies how corners are drawn when a shape is stroked. Join
|
||||
affects the four corners of a stroked rectangle, and the connected segments in a
|
||||
stroked path.
|
||||
|
||||
Choose miter join to draw sharp corners. Choose round join to draw a circle with a
|
||||
radius equal to the stroke width on top of the corner. Choose bevel join to minimally
|
||||
connect the thick strokes.
|
||||
|
||||
The fill path constructed to describe the stroked path respects the join setting but may
|
||||
not contain the actual join. For instance, a fill path constructed with round joins does
|
||||
not necessarily include circles at each connected segment.
|
||||
*/
|
||||
enum Join : uint8_t {
|
||||
kMiter_Join, //!< extends to miter limit
|
||||
kRound_Join, //!< adds circle
|
||||
kBevel_Join, //!< connects outside edges
|
||||
kLast_Join = kBevel_Join, //!< equivalent to the largest value for Join
|
||||
kDefault_Join = kMiter_Join, //!< equivalent to kMiter_Join
|
||||
};
|
||||
|
||||
/** May be used to verify that SkPaint::Join is a legal value.
|
||||
*/
|
||||
static constexpr int kJoinCount = kLast_Join + 1;
|
||||
|
||||
/** Returns the geometry drawn at the beginning and end of strokes.
|
||||
*/
|
||||
Cap getStrokeCap() const { return (Cap)fBitfields.fCapType; }
|
||||
|
||||
/** Sets the geometry drawn at the beginning and end of strokes.
|
||||
|
||||
example: https://fiddle.skia.org/c/@Paint_setStrokeCap_a
|
||||
example: https://fiddle.skia.org/c/@Paint_setStrokeCap_b
|
||||
*/
|
||||
void setStrokeCap(Cap cap);
|
||||
|
||||
/** Returns the geometry drawn at the corners of strokes.
|
||||
*/
|
||||
Join getStrokeJoin() const { return (Join)fBitfields.fJoinType; }
|
||||
|
||||
/** Sets the geometry drawn at the corners of strokes.
|
||||
|
||||
example: https://fiddle.skia.org/c/@Paint_setStrokeJoin
|
||||
*/
|
||||
void setStrokeJoin(Join join);
|
||||
|
||||
/** Returns optional colors used when filling a path, such as a gradient.
|
||||
|
||||
Does not alter SkShader SkRefCnt.
|
||||
|
||||
@return SkShader if previously set, nullptr otherwise
|
||||
*/
|
||||
SkShader* getShader() const { return fShader.get(); }
|
||||
|
||||
/** Returns optional colors used when filling a path, such as a gradient.
|
||||
|
||||
Increases SkShader SkRefCnt by one.
|
||||
|
||||
@return SkShader if previously set, nullptr otherwise
|
||||
|
||||
example: https://fiddle.skia.org/c/@Paint_refShader
|
||||
*/
|
||||
sk_sp<SkShader> refShader() const;
|
||||
|
||||
/** Sets optional colors used when filling a path, such as a gradient.
|
||||
|
||||
Sets SkShader to shader, decreasing SkRefCnt of the previous SkShader.
|
||||
Increments shader SkRefCnt by one.
|
||||
|
||||
@param shader how geometry is filled with color; if nullptr, color is used instead
|
||||
|
||||
example: https://fiddle.skia.org/c/@Color_Filter_Methods
|
||||
example: https://fiddle.skia.org/c/@Paint_setShader
|
||||
*/
|
||||
void setShader(sk_sp<SkShader> shader);
|
||||
|
||||
/** Returns SkColorFilter if set, or nullptr.
|
||||
Does not alter SkColorFilter SkRefCnt.
|
||||
|
||||
@return SkColorFilter if previously set, nullptr otherwise
|
||||
*/
|
||||
SkColorFilter* getColorFilter() const { return fColorFilter.get(); }
|
||||
|
||||
/** Returns SkColorFilter if set, or nullptr.
|
||||
Increases SkColorFilter SkRefCnt by one.
|
||||
|
||||
@return SkColorFilter if set, or nullptr
|
||||
|
||||
example: https://fiddle.skia.org/c/@Paint_refColorFilter
|
||||
*/
|
||||
sk_sp<SkColorFilter> refColorFilter() const;
|
||||
|
||||
/** Sets SkColorFilter to filter, decreasing SkRefCnt of the previous
|
||||
SkColorFilter. Pass nullptr to clear SkColorFilter.
|
||||
|
||||
Increments filter SkRefCnt by one.
|
||||
|
||||
@param colorFilter SkColorFilter to apply to subsequent draw
|
||||
|
||||
example: https://fiddle.skia.org/c/@Blend_Mode_Methods
|
||||
example: https://fiddle.skia.org/c/@Paint_setColorFilter
|
||||
*/
|
||||
void setColorFilter(sk_sp<SkColorFilter> colorFilter);
|
||||
|
||||
/** If the current blender can be represented as a SkBlendMode enum, this returns that
|
||||
* enum in the optional's value(). If it cannot, then the returned optional does not
|
||||
* contain a value.
|
||||
*/
|
||||
std::optional<SkBlendMode> asBlendMode() const;
|
||||
|
||||
/**
|
||||
* Queries the blender, and if it can be represented as a SkBlendMode, return that mode,
|
||||
* else return the defaultMode provided.
|
||||
*/
|
||||
SkBlendMode getBlendMode_or(SkBlendMode defaultMode) const;
|
||||
|
||||
/** Returns true iff the current blender claims to be equivalent to SkBlendMode::kSrcOver.
|
||||
*
|
||||
* Also returns true of the current blender is nullptr.
|
||||
*/
|
||||
bool isSrcOver() const;
|
||||
|
||||
/** Helper method for calling setBlender().
|
||||
*
|
||||
* This sets a blender that implements the specified blendmode enum.
|
||||
*/
|
||||
void setBlendMode(SkBlendMode mode);
|
||||
|
||||
/** Returns the user-supplied blend function, if one has been set.
|
||||
* Does not alter SkBlender's SkRefCnt.
|
||||
*
|
||||
* A nullptr blender signifies the default SrcOver behavior.
|
||||
*
|
||||
* @return the SkBlender assigned to this paint, otherwise nullptr
|
||||
*/
|
||||
SkBlender* getBlender() const { return fBlender.get(); }
|
||||
|
||||
/** Returns the user-supplied blend function, if one has been set.
|
||||
* Increments the SkBlender's SkRefCnt by one.
|
||||
*
|
||||
* A nullptr blender signifies the default SrcOver behavior.
|
||||
*
|
||||
* @return the SkBlender assigned to this paint, otherwise nullptr
|
||||
*/
|
||||
sk_sp<SkBlender> refBlender() const;
|
||||
|
||||
/** Sets the current blender, increasing its refcnt, and if a blender is already
|
||||
* present, decreasing that object's refcnt.
|
||||
*
|
||||
* A nullptr blender signifies the default SrcOver behavior.
|
||||
*
|
||||
* For convenience, you can call setBlendMode() if the blend effect can be expressed
|
||||
* as one of those values.
|
||||
*/
|
||||
void setBlender(sk_sp<SkBlender> blender);
|
||||
|
||||
/** Returns SkPathEffect if set, or nullptr.
|
||||
Does not alter SkPathEffect SkRefCnt.
|
||||
|
||||
@return SkPathEffect if previously set, nullptr otherwise
|
||||
*/
|
||||
SkPathEffect* getPathEffect() const { return fPathEffect.get(); }
|
||||
|
||||
/** Returns SkPathEffect if set, or nullptr.
|
||||
Increases SkPathEffect SkRefCnt by one.
|
||||
|
||||
@return SkPathEffect if previously set, nullptr otherwise
|
||||
|
||||
example: https://fiddle.skia.org/c/@Paint_refPathEffect
|
||||
*/
|
||||
sk_sp<SkPathEffect> refPathEffect() const;
|
||||
|
||||
/** Sets SkPathEffect to pathEffect, decreasing SkRefCnt of the previous
|
||||
SkPathEffect. Pass nullptr to leave the path geometry unaltered.
|
||||
|
||||
Increments pathEffect SkRefCnt by one.
|
||||
|
||||
@param pathEffect replace SkPath with a modification when drawn
|
||||
|
||||
example: https://fiddle.skia.org/c/@Mask_Filter_Methods
|
||||
example: https://fiddle.skia.org/c/@Paint_setPathEffect
|
||||
*/
|
||||
void setPathEffect(sk_sp<SkPathEffect> pathEffect);
|
||||
|
||||
/** Returns SkMaskFilter if set, or nullptr.
|
||||
Does not alter SkMaskFilter SkRefCnt.
|
||||
|
||||
@return SkMaskFilter if previously set, nullptr otherwise
|
||||
*/
|
||||
SkMaskFilter* getMaskFilter() const { return fMaskFilter.get(); }
|
||||
|
||||
/** Returns SkMaskFilter if set, or nullptr.
|
||||
|
||||
Increases SkMaskFilter SkRefCnt by one.
|
||||
|
||||
@return SkMaskFilter if previously set, nullptr otherwise
|
||||
|
||||
example: https://fiddle.skia.org/c/@Paint_refMaskFilter
|
||||
*/
|
||||
sk_sp<SkMaskFilter> refMaskFilter() const;
|
||||
|
||||
/** Sets SkMaskFilter to maskFilter, decreasing SkRefCnt of the previous
|
||||
SkMaskFilter. Pass nullptr to clear SkMaskFilter and leave SkMaskFilter effect on
|
||||
mask alpha unaltered.
|
||||
|
||||
Increments maskFilter SkRefCnt by one.
|
||||
|
||||
@param maskFilter modifies clipping mask generated from drawn geometry
|
||||
|
||||
example: https://fiddle.skia.org/c/@Paint_setMaskFilter
|
||||
example: https://fiddle.skia.org/c/@Typeface_Methods
|
||||
*/
|
||||
void setMaskFilter(sk_sp<SkMaskFilter> maskFilter);
|
||||
|
||||
/** Returns SkImageFilter if set, or nullptr.
|
||||
Does not alter SkImageFilter SkRefCnt.
|
||||
|
||||
@return SkImageFilter if previously set, nullptr otherwise
|
||||
*/
|
||||
SkImageFilter* getImageFilter() const { return fImageFilter.get(); }
|
||||
|
||||
/** Returns SkImageFilter if set, or nullptr.
|
||||
Increases SkImageFilter SkRefCnt by one.
|
||||
|
||||
@return SkImageFilter if previously set, nullptr otherwise
|
||||
|
||||
example: https://fiddle.skia.org/c/@Paint_refImageFilter
|
||||
*/
|
||||
sk_sp<SkImageFilter> refImageFilter() const;
|
||||
|
||||
/** Sets SkImageFilter to imageFilter, decreasing SkRefCnt of the previous
|
||||
SkImageFilter. Pass nullptr to clear SkImageFilter, and remove SkImageFilter effect
|
||||
on drawing.
|
||||
|
||||
Increments imageFilter SkRefCnt by one.
|
||||
|
||||
@param imageFilter how SkImage is sampled when transformed
|
||||
|
||||
example: https://fiddle.skia.org/c/@Paint_setImageFilter
|
||||
*/
|
||||
void setImageFilter(sk_sp<SkImageFilter> imageFilter);
|
||||
|
||||
/** Returns true if SkPaint prevents all drawing;
|
||||
otherwise, the SkPaint may or may not allow drawing.
|
||||
|
||||
Returns true if, for example, SkBlendMode combined with alpha computes a
|
||||
new alpha of zero.
|
||||
|
||||
@return true if SkPaint prevents all drawing
|
||||
|
||||
example: https://fiddle.skia.org/c/@Paint_nothingToDraw
|
||||
*/
|
||||
bool nothingToDraw() const;
|
||||
|
||||
/** (to be made private)
|
||||
Returns true if SkPaint does not include elements requiring extensive computation
|
||||
to compute device bounds of drawn geometry. For instance, SkPaint with SkPathEffect
|
||||
always returns false.
|
||||
|
||||
@return true if SkPaint allows for fast computation of bounds
|
||||
*/
|
||||
bool canComputeFastBounds() const;
|
||||
|
||||
/** (to be made private)
|
||||
Only call this if canComputeFastBounds() returned true. This takes a
|
||||
raw rectangle (the raw bounds of a shape), and adjusts it for stylistic
|
||||
effects in the paint (e.g. stroking). If needed, it uses the storage
|
||||
parameter. It returns the adjusted bounds that can then be used
|
||||
for SkCanvas::quickReject tests.
|
||||
|
||||
The returned SkRect will either be orig or storage, thus the caller
|
||||
should not rely on storage being set to the result, but should always
|
||||
use the returned value. It is legal for orig and storage to be the same
|
||||
SkRect.
|
||||
For example:
|
||||
if (!path.isInverseFillType() && paint.canComputeFastBounds()) {
|
||||
SkRect storage;
|
||||
if (canvas->quickReject(paint.computeFastBounds(path.getBounds(), &storage))) {
|
||||
return; // do not draw the path
|
||||
}
|
||||
}
|
||||
// draw the path
|
||||
|
||||
@param orig geometry modified by SkPaint when drawn
|
||||
@param storage computed bounds of geometry; may not be nullptr
|
||||
@return fast computed bounds
|
||||
*/
|
||||
const SkRect& computeFastBounds(const SkRect& orig, SkRect* storage) const;
|
||||
|
||||
/** (to be made private)
|
||||
|
||||
@param orig geometry modified by SkPaint when drawn
|
||||
@param storage computed bounds of geometry
|
||||
@return fast computed bounds
|
||||
*/
|
||||
const SkRect& computeFastStrokeBounds(const SkRect& orig,
|
||||
SkRect* storage) const {
|
||||
return this->doComputeFastBounds(orig, storage, kStroke_Style);
|
||||
}
|
||||
|
||||
/** (to be made private)
|
||||
Computes the bounds, overriding the SkPaint SkPaint::Style. This can be used to
|
||||
account for additional width required by stroking orig, without
|
||||
altering SkPaint::Style set to fill.
|
||||
|
||||
@param orig geometry modified by SkPaint when drawn
|
||||
@param storage computed bounds of geometry
|
||||
@param style overrides SkPaint::Style
|
||||
@return fast computed bounds
|
||||
*/
|
||||
const SkRect& doComputeFastBounds(const SkRect& orig, SkRect* storage,
|
||||
Style style) const;
|
||||
|
||||
using sk_is_trivially_relocatable = std::true_type;
|
||||
|
||||
private:
|
||||
sk_sp<SkPathEffect> fPathEffect;
|
||||
sk_sp<SkShader> fShader;
|
||||
sk_sp<SkMaskFilter> fMaskFilter;
|
||||
sk_sp<SkColorFilter> fColorFilter;
|
||||
sk_sp<SkImageFilter> fImageFilter;
|
||||
sk_sp<SkBlender> fBlender;
|
||||
|
||||
SkColor4f fColor4f;
|
||||
SkScalar fWidth;
|
||||
SkScalar fMiterLimit;
|
||||
union {
|
||||
struct {
|
||||
unsigned fAntiAlias : 1;
|
||||
unsigned fDither : 1;
|
||||
unsigned fCapType : 2;
|
||||
unsigned fJoinType : 2;
|
||||
unsigned fStyle : 2;
|
||||
unsigned fPadding : 24; // 24 == 32 -1-1-2-2-2
|
||||
} fBitfields;
|
||||
uint32_t fBitfieldsUInt;
|
||||
};
|
||||
|
||||
static_assert(::sk_is_trivially_relocatable<decltype(fPathEffect)>::value);
|
||||
static_assert(::sk_is_trivially_relocatable<decltype(fShader)>::value);
|
||||
static_assert(::sk_is_trivially_relocatable<decltype(fMaskFilter)>::value);
|
||||
static_assert(::sk_is_trivially_relocatable<decltype(fColorFilter)>::value);
|
||||
static_assert(::sk_is_trivially_relocatable<decltype(fImageFilter)>::value);
|
||||
static_assert(::sk_is_trivially_relocatable<decltype(fBlender)>::value);
|
||||
static_assert(::sk_is_trivially_relocatable<decltype(fColor4f)>::value);
|
||||
static_assert(::sk_is_trivially_relocatable<decltype(fBitfields)>::value);
|
||||
|
||||
friend class SkPaintPriv;
|
||||
};
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* 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 SkPathEffect_DEFINED
|
||||
#define SkPathEffect_DEFINED
|
||||
|
||||
#include "include/core/SkFlattenable.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/core/SkTypes.h"
|
||||
|
||||
// TODO(kjlubick) update clients and remove this unnecessary #include
|
||||
#include "include/core/SkPath.h" // IWYU pragma: keep
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
class SkMatrix;
|
||||
class SkPathBuilder;
|
||||
class SkStrokeRec;
|
||||
struct SkDeserialProcs;
|
||||
struct SkRect;
|
||||
|
||||
/** \class SkPathEffect
|
||||
|
||||
SkPathEffect is the base class for objects in the SkPaint that affect
|
||||
the geometry of a drawing primitive before it is transformed by the
|
||||
canvas' matrix and drawn.
|
||||
|
||||
Dashing is implemented as a subclass of SkPathEffect.
|
||||
*/
|
||||
class SK_API SkPathEffect : public SkFlattenable {
|
||||
public:
|
||||
/**
|
||||
* Returns a patheffect that apples each effect (first and second) to the original path,
|
||||
* and returns a path with the sum of these.
|
||||
*
|
||||
* result = first(path) + second(path)
|
||||
*
|
||||
*/
|
||||
static sk_sp<SkPathEffect> MakeSum(sk_sp<SkPathEffect> first, sk_sp<SkPathEffect> second);
|
||||
|
||||
/**
|
||||
* Returns a patheffect that applies the inner effect to the path, and then applies the
|
||||
* outer effect to the result of the inner's.
|
||||
*
|
||||
* result = outer(inner(path))
|
||||
*/
|
||||
static sk_sp<SkPathEffect> MakeCompose(sk_sp<SkPathEffect> outer, sk_sp<SkPathEffect> inner);
|
||||
|
||||
static SkFlattenable::Type GetFlattenableType() {
|
||||
return kSkPathEffect_Type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a src path (input) and a stroke-rec (input and output), apply
|
||||
* this effect to the src path, returning the new path in dst, and return
|
||||
* true. If this effect cannot be applied, return false and ignore dst
|
||||
* and stroke-rec.
|
||||
*
|
||||
* The stroke-rec specifies the initial request for stroking (if any).
|
||||
* The effect can treat this as input only, or it can choose to change
|
||||
* the rec as well. For example, the effect can decide to change the
|
||||
* stroke's width or join, or the effect can change the rec from stroke
|
||||
* to fill (or fill to stroke) in addition to returning a new (dst) path.
|
||||
*
|
||||
* If this method returns true, the caller will apply (as needed) the
|
||||
* resulting stroke-rec to dst and then draw.
|
||||
*/
|
||||
bool filterPath(SkPathBuilder* dst, const SkPath& src, SkStrokeRec*, const SkRect* cullR,
|
||||
const SkMatrix& ctm) const;
|
||||
bool filterPath(SkPathBuilder* dst, const SkPath& src, SkStrokeRec*) const;
|
||||
|
||||
/** True if this path effect requires a valid CTM */
|
||||
bool needsCTM() const;
|
||||
|
||||
static sk_sp<SkPathEffect> Deserialize(const void* data, size_t size,
|
||||
const SkDeserialProcs* procs = nullptr);
|
||||
private:
|
||||
SkPathEffect() = default;
|
||||
friend class SkPathEffectBase;
|
||||
|
||||
using INHERITED = SkFlattenable;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright 2025 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkPathIter_DEFINED
|
||||
#define SkPathIter_DEFINED
|
||||
|
||||
#include "include/core/SkPathTypes.h"
|
||||
#include "include/core/SkPoint.h"
|
||||
#include "include/core/SkSpan.h"
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <optional>
|
||||
|
||||
class SK_API SkPathIter {
|
||||
public:
|
||||
struct Rec {
|
||||
SkSpan<const SkPoint> fPoints;
|
||||
float fConicWeight;
|
||||
SkPathVerb fVerb;
|
||||
|
||||
float conicWeight() const {
|
||||
SkASSERT(fVerb == SkPathVerb::kConic);
|
||||
return fConicWeight;
|
||||
}
|
||||
};
|
||||
|
||||
SkPathIter(SkSpan<const SkPoint> pts, SkSpan<const SkPathVerb> vbs, SkSpan<const float> cns)
|
||||
: pIndex(0), vIndex(0), cIndex(0)
|
||||
, fPoints(pts), fVerbs(vbs), fConics(cns)
|
||||
{
|
||||
// For compat older iterators, we trim off a trailing Move.
|
||||
// SkPathData is defined to never create this pattern, so perhaps in the future
|
||||
// this check can be removed (or replaced by an assert)
|
||||
if (!vbs.empty() && vbs.back() == SkPathVerb::kMove) {
|
||||
fVerbs = vbs.first(vbs.size() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Holds the current verb, and its associated points
|
||||
* move: pts[0]
|
||||
* line: pts[0..1]
|
||||
* quad: pts[0..2]
|
||||
* conic: pts[0..2] fConicWeight
|
||||
* cubic: pts[0..3]
|
||||
* close: pts[0..1] ... as if close were a line from pts[0] to pts[1]
|
||||
*/
|
||||
std::optional<Rec> next();
|
||||
|
||||
std::optional<SkPathVerb> peekNextVerb() const {
|
||||
if (vIndex < fVerbs.size()) {
|
||||
return fVerbs[vIndex];
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
private:
|
||||
size_t pIndex, vIndex, cIndex;
|
||||
SkSpan<const SkPoint> fPoints;
|
||||
SkSpan<const SkPathVerb> fVerbs;
|
||||
SkSpan<const float> fConics;
|
||||
std::array<SkPoint, 2> fClosePointStorage;
|
||||
};
|
||||
|
||||
class SkPathContourIter {
|
||||
public:
|
||||
struct Rec {
|
||||
SkSpan<const SkPoint> fPoints;
|
||||
SkSpan<const SkPathVerb> fVerbs;
|
||||
SkSpan<const float> fConics;
|
||||
};
|
||||
|
||||
SkPathContourIter(SkSpan<const SkPoint> pts, SkSpan<const SkPathVerb> vbs,
|
||||
SkSpan<const float> cns)
|
||||
: fPoints(pts), fVerbs(vbs), fConics(cns)
|
||||
{}
|
||||
|
||||
std::optional<Rec> next();
|
||||
|
||||
private:
|
||||
SkSpan<const SkPoint> fPoints;
|
||||
SkSpan<const SkPathVerb> fVerbs;
|
||||
SkSpan<const float> fConics;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* 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 SkPathMeasure_DEFINED
|
||||
#define SkPathMeasure_DEFINED
|
||||
|
||||
#include "include/core/SkContourMeasure.h"
|
||||
#include "include/core/SkPoint.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/core/SkScalar.h"
|
||||
#include "include/core/SkTypes.h"
|
||||
#include "include/private/base/SkDebug.h"
|
||||
|
||||
class SkMatrix;
|
||||
class SkPath;
|
||||
class SkPathBuilder;
|
||||
|
||||
class SK_API SkPathMeasure {
|
||||
public:
|
||||
SkPathMeasure();
|
||||
/** Initialize the pathmeasure with the specified path. The parts of the path that are needed
|
||||
* are copied, so the client is free to modify/delete the path after this call.
|
||||
*
|
||||
* resScale controls the precision of the measure. values > 1 increase the
|
||||
* precision (and possibly slow down the computation).
|
||||
*/
|
||||
SkPathMeasure(const SkPath& path, bool forceClosed, SkScalar resScale = 1);
|
||||
~SkPathMeasure();
|
||||
|
||||
SkPathMeasure(SkPathMeasure&&) = default;
|
||||
SkPathMeasure& operator=(SkPathMeasure&&) = default;
|
||||
|
||||
/** Reset the pathmeasure with the specified path. The parts of the path that are needed
|
||||
* are copied, so the client is free to modify/delete the path after this call..
|
||||
*/
|
||||
void setPath(const SkPath*, bool forceClosed);
|
||||
|
||||
/** Return the total length of the current contour, or 0 if no path
|
||||
is associated (e.g. resetPath(null))
|
||||
*/
|
||||
SkScalar getLength();
|
||||
|
||||
/** Pins distance to 0 <= distance <= getLength(), and then computes
|
||||
the corresponding position and tangent.
|
||||
Returns false if there is no path, or a zero-length path was specified, in which case
|
||||
position and tangent are unchanged.
|
||||
*/
|
||||
[[nodiscard]] bool getPosTan(SkScalar distance, SkPoint* position, SkVector* tangent);
|
||||
|
||||
enum MatrixFlags {
|
||||
kGetPosition_MatrixFlag = 0x01,
|
||||
kGetTangent_MatrixFlag = 0x02,
|
||||
kGetPosAndTan_MatrixFlag = kGetPosition_MatrixFlag | kGetTangent_MatrixFlag
|
||||
};
|
||||
|
||||
/** Pins distance to 0 <= distance <= getLength(), and then computes
|
||||
the corresponding matrix (by calling getPosTan).
|
||||
Returns false if there is no path, or a zero-length path was specified, in which case
|
||||
matrix is unchanged.
|
||||
*/
|
||||
[[nodiscard]] bool getMatrix(SkScalar distance, SkMatrix* matrix,
|
||||
MatrixFlags flags = kGetPosAndTan_MatrixFlag);
|
||||
|
||||
/** Given a start and stop distance, append to dst the intervening segment(s).
|
||||
If the segment is zero-length, return false, else return true.
|
||||
startD and stopD are pinned to legal values (0..getLength()). If startD > stopD
|
||||
then return false (and leave dst untouched).
|
||||
Begin the segment with a moveTo if startWithMoveTo is true
|
||||
*/
|
||||
bool getSegment(SkScalar startD, SkScalar stopD, SkPathBuilder* dst, bool startWithMoveTo);
|
||||
|
||||
/** Return true if the current contour is closed()
|
||||
*/
|
||||
bool isClosed();
|
||||
|
||||
/** Move to the next contour in the path. Return true if one exists, or false if
|
||||
we're done with the path.
|
||||
*/
|
||||
bool nextContour();
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
void dump();
|
||||
#endif
|
||||
|
||||
const SkContourMeasure* currentMeasure() const { return fContour.get(); }
|
||||
|
||||
private:
|
||||
SkContourMeasureIter fIter;
|
||||
sk_sp<SkContourMeasure> fContour;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright 2019 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkPathTypes_DEFINED
|
||||
#define SkPathTypes_DEFINED
|
||||
|
||||
#include "include/core/SkTypes.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
enum class SkPathFillType : uint8_t {
|
||||
/** Specifies that "inside" is computed by a non-zero sum of signed edge crossings */
|
||||
kWinding,
|
||||
/** Specifies that "inside" is computed by an odd number of edge crossings */
|
||||
kEvenOdd,
|
||||
/** Same as Winding, but draws outside of the path, rather than inside */
|
||||
kInverseWinding,
|
||||
/** Same as EvenOdd, but draws outside of the path, rather than inside */
|
||||
kInverseEvenOdd,
|
||||
|
||||
kDefault = kWinding,
|
||||
};
|
||||
|
||||
static inline bool SkPathFillType_IsEvenOdd(SkPathFillType ft) {
|
||||
return (static_cast<int>(ft) & 1) != 0;
|
||||
}
|
||||
|
||||
static inline bool SkPathFillType_IsInverse(SkPathFillType ft) {
|
||||
return (static_cast<int>(ft) & 2) != 0;
|
||||
}
|
||||
|
||||
static inline SkPathFillType SkPathFillType_ToggleInverse(SkPathFillType ft) {
|
||||
return static_cast<SkPathFillType>(static_cast<int>(ft) ^ 2);
|
||||
}
|
||||
|
||||
static inline SkPathFillType SkPathFillType_ConvertToNonInverse(SkPathFillType ft) {
|
||||
return static_cast<SkPathFillType>(static_cast<int>(ft) & 1);
|
||||
}
|
||||
|
||||
enum class SkPathDirection : uint8_t {
|
||||
/** clockwise direction for adding closed contours */
|
||||
kCW,
|
||||
/** counter-clockwise direction for adding closed contours */
|
||||
kCCW,
|
||||
|
||||
kDefault = kCW,
|
||||
};
|
||||
|
||||
enum SkPathSegmentMask {
|
||||
kLine_SkPathSegmentMask = 1 << 0,
|
||||
kQuad_SkPathSegmentMask = 1 << 1,
|
||||
kConic_SkPathSegmentMask = 1 << 2,
|
||||
kCubic_SkPathSegmentMask = 1 << 3,
|
||||
};
|
||||
|
||||
enum class SkPathVerb : uint8_t {
|
||||
kMove, //!< SkPath::RawIter returns 1 point
|
||||
kLine, //!< SkPath::RawIter returns 2 points
|
||||
kQuad, //!< SkPath::RawIter returns 3 points
|
||||
kConic, //!< SkPath::RawIter returns 3 points + 1 weight
|
||||
kCubic, //!< SkPath::RawIter returns 4 points
|
||||
kClose, //!< SkPath::RawIter returns 0 points
|
||||
|
||||
kLast_Verb = kClose,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2022 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
#ifndef SkPathUtils_DEFINED
|
||||
#define SkPathUtils_DEFINED
|
||||
|
||||
#include "include/core/SkScalar.h" // IWYU pragma: keep
|
||||
#include "include/core/SkTypes.h"
|
||||
|
||||
class SkMatrix;
|
||||
class SkPaint;
|
||||
class SkPath;
|
||||
class SkPathBuilder;
|
||||
struct SkRect;
|
||||
|
||||
namespace skpathutils {
|
||||
|
||||
/* Returns the filled equivalent of the stroked path.
|
||||
*
|
||||
* @param src SkPath read to create a filled version
|
||||
* @param paint uses settings for stroke cap, width, miter, join, and patheffect.
|
||||
* @param dst results are written to this builder.
|
||||
* @param cullRect optional limit passed to SkPathEffect
|
||||
* @param ctm matrix to take into acount for increased precision (if it scales up).
|
||||
* @return true if the result can be filled, or false if it is a hairline (to be stroked).
|
||||
*/
|
||||
SK_API bool FillPathWithPaint(const SkPath& src, const SkPaint& paint, SkPathBuilder* dst,
|
||||
const SkRect* cullRect, const SkMatrix& ctm);
|
||||
|
||||
SK_API bool FillPathWithPaint(const SkPath& src, const SkPaint& paint, SkPathBuilder* dst);
|
||||
|
||||
SK_API SkPath FillPathWithPaint(const SkPath& src, const SkPaint& paint, bool* isFill = nullptr);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,291 @@
|
|||
/*
|
||||
* Copyright 2007 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 SkPicture_DEFINED
|
||||
#define SkPicture_DEFINED
|
||||
|
||||
#include "include/core/SkRect.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/core/SkShader.h" // IWYU pragma: keep
|
||||
#include "include/core/SkTypes.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
class SkCanvas;
|
||||
class SkData;
|
||||
class SkMatrix;
|
||||
class SkStream;
|
||||
class SkWStream;
|
||||
enum class SkFilterMode;
|
||||
struct SkDeserialProcs;
|
||||
struct SkSerialProcs;
|
||||
|
||||
// TODO(kjlubick) Remove this after cleaning up clients
|
||||
#include "include/core/SkTileMode.h" // IWYU pragma: keep
|
||||
|
||||
/** \class SkPicture
|
||||
SkPicture records drawing commands made to SkCanvas. The command stream may be
|
||||
played in whole or in part at a later time.
|
||||
|
||||
SkPicture is an abstract class. SkPicture may be generated by SkPictureRecorder
|
||||
or SkDrawable, or from SkPicture previously saved to SkData or SkStream.
|
||||
|
||||
SkPicture may contain any SkCanvas drawing command, as well as one or more
|
||||
SkCanvas matrix or SkCanvas clip. SkPicture has a cull SkRect, which is used as
|
||||
a bounding box hint. To limit SkPicture bounds, use SkCanvas clip when
|
||||
recording or drawing SkPicture.
|
||||
*/
|
||||
class SK_API SkPicture : public SkRefCnt {
|
||||
public:
|
||||
~SkPicture() override;
|
||||
|
||||
/** Recreates SkPicture that was serialized into a stream. Returns constructed SkPicture
|
||||
if successful; otherwise, returns nullptr. Fails if data does not permit
|
||||
constructing valid SkPicture.
|
||||
|
||||
procs->fPictureProc permits supplying a custom function to decode SkPicture.
|
||||
If procs->fPictureProc is nullptr, default decoding is used. procs->fPictureCtx
|
||||
may be used to provide user context to procs->fPictureProc; procs->fPictureProc
|
||||
is called with a pointer to data, data byte length, and user context.
|
||||
|
||||
@param stream container for serial data
|
||||
@param procs custom serial data decoders; may be nullptr
|
||||
@return SkPicture constructed from stream data
|
||||
*/
|
||||
static sk_sp<SkPicture> MakeFromStream(SkStream* stream,
|
||||
const SkDeserialProcs* procs = nullptr);
|
||||
|
||||
/** Recreates SkPicture that was serialized into data. Returns constructed SkPicture
|
||||
if successful; otherwise, returns nullptr. Fails if data does not permit
|
||||
constructing valid SkPicture.
|
||||
|
||||
procs->fPictureProc permits supplying a custom function to decode SkPicture.
|
||||
If procs->fPictureProc is nullptr, default decoding is used. procs->fPictureCtx
|
||||
may be used to provide user context to procs->fPictureProc; procs->fPictureProc
|
||||
is called with a pointer to data, data byte length, and user context.
|
||||
|
||||
@param data container for serial data
|
||||
@param procs custom serial data decoders; may be nullptr
|
||||
@return SkPicture constructed from data
|
||||
*/
|
||||
static sk_sp<SkPicture> MakeFromData(const SkData* data,
|
||||
const SkDeserialProcs* procs = nullptr);
|
||||
|
||||
/**
|
||||
|
||||
@param data pointer to serial data
|
||||
@param size size of data
|
||||
@param procs custom serial data decoders; may be nullptr
|
||||
@return SkPicture constructed from data
|
||||
*/
|
||||
static sk_sp<SkPicture> MakeFromData(const void* data, size_t size,
|
||||
const SkDeserialProcs* procs = nullptr);
|
||||
|
||||
/** \class SkPicture::AbortCallback
|
||||
AbortCallback is an abstract class. An implementation of AbortCallback may
|
||||
passed as a parameter to SkPicture::playback, to stop it before all drawing
|
||||
commands have been processed.
|
||||
|
||||
If AbortCallback::abort returns true, SkPicture::playback is interrupted.
|
||||
*/
|
||||
class SK_API AbortCallback {
|
||||
public:
|
||||
/** Has no effect.
|
||||
*/
|
||||
virtual ~AbortCallback() = default;
|
||||
|
||||
/** Stops SkPicture playback when some condition is met. A subclass of
|
||||
AbortCallback provides an override for abort() that can stop SkPicture::playback.
|
||||
|
||||
The part of SkPicture drawn when aborted is undefined. SkPicture instantiations are
|
||||
free to stop drawing at different points during playback.
|
||||
|
||||
If the abort happens inside one or more calls to SkCanvas::save(), stack
|
||||
of SkCanvas matrix and SkCanvas clip values is restored to its state before
|
||||
SkPicture::playback was called.
|
||||
|
||||
@return true to stop playback
|
||||
|
||||
example: https://fiddle.skia.org/c/@Picture_AbortCallback_abort
|
||||
*/
|
||||
virtual bool abort() = 0;
|
||||
|
||||
protected:
|
||||
AbortCallback() = default;
|
||||
AbortCallback(const AbortCallback&) = delete;
|
||||
AbortCallback& operator=(const AbortCallback&) = delete;
|
||||
};
|
||||
|
||||
/** Replays the drawing commands on the specified canvas. In the case that the
|
||||
commands are recorded, each command in the SkPicture is sent separately to canvas.
|
||||
|
||||
To add a single command to draw SkPicture to recording canvas, call
|
||||
SkCanvas::drawPicture instead.
|
||||
|
||||
@param canvas receiver of drawing commands
|
||||
@param callback allows interruption of playback
|
||||
|
||||
example: https://fiddle.skia.org/c/@Picture_playback
|
||||
*/
|
||||
virtual void playback(SkCanvas* canvas, AbortCallback* callback = nullptr) const = 0;
|
||||
|
||||
/** Returns cull SkRect for this picture, passed in when SkPicture was created.
|
||||
Returned SkRect does not specify clipping SkRect for SkPicture; cull is hint
|
||||
of SkPicture bounds.
|
||||
|
||||
SkPicture is free to discard recorded drawing commands that fall outside
|
||||
cull.
|
||||
|
||||
@return bounds passed when SkPicture was created
|
||||
|
||||
example: https://fiddle.skia.org/c/@Picture_cullRect
|
||||
*/
|
||||
virtual SkRect cullRect() const = 0;
|
||||
|
||||
/** Returns a non-zero value unique among SkPicture in Skia process.
|
||||
|
||||
@return identifier for SkPicture
|
||||
*/
|
||||
uint32_t uniqueID() const { return fUniqueID; }
|
||||
|
||||
/** Returns storage containing SkData describing SkPicture, using optional custom
|
||||
encoders.
|
||||
|
||||
procs->fPictureProc permits supplying a custom function to encode SkPicture.
|
||||
If procs->fPictureProc is nullptr, default encoding is used. procs->fPictureCtx
|
||||
may be used to provide user context to procs->fPictureProc; procs->fPictureProc
|
||||
is called with a pointer to SkPicture and user context.
|
||||
|
||||
The default behavior for serializing SkImages is to encode a nullptr. Should
|
||||
clients want to, for example, encode these SkImages as PNGs so they can be
|
||||
deserialized, they must provide SkSerialProcs with the fImageProc set to do so.
|
||||
|
||||
@param procs custom serial data encoders; may be nullptr
|
||||
@return storage containing serialized SkPicture
|
||||
|
||||
example: https://fiddle.skia.org/c/@Picture_serialize
|
||||
*/
|
||||
sk_sp<SkData> serialize(const SkSerialProcs* procs = nullptr) const;
|
||||
|
||||
/** Writes picture to stream, using optional custom encoders.
|
||||
|
||||
procs->fPictureProc permits supplying a custom function to encode SkPicture.
|
||||
If procs->fPictureProc is nullptr, default encoding is used. procs->fPictureCtx
|
||||
may be used to provide user context to procs->fPictureProc; procs->fPictureProc
|
||||
is called with a pointer to SkPicture and user context.
|
||||
|
||||
The default behavior for serializing SkImages is to encode a nullptr. Should
|
||||
clients want to, for example, encode these SkImages as PNGs so they can be
|
||||
deserialized, they must provide SkSerialProcs with the fImageProc set to do so.
|
||||
|
||||
@param stream writable serial data stream
|
||||
@param procs custom serial data encoders; may be nullptr
|
||||
|
||||
example: https://fiddle.skia.org/c/@Picture_serialize_2
|
||||
*/
|
||||
void serialize(SkWStream* stream, const SkSerialProcs* procs = nullptr) const;
|
||||
|
||||
/** Returns a placeholder SkPicture. Result does not draw, and contains only
|
||||
cull SkRect, a hint of its bounds. Result is immutable; it cannot be changed
|
||||
later. Result identifier is unique.
|
||||
|
||||
Returned placeholder can be intercepted during playback to insert other
|
||||
commands into SkCanvas draw stream.
|
||||
|
||||
@param cull placeholder dimensions
|
||||
@return placeholder with unique identifier
|
||||
|
||||
example: https://fiddle.skia.org/c/@Picture_MakePlaceholder
|
||||
*/
|
||||
static sk_sp<SkPicture> MakePlaceholder(SkRect cull);
|
||||
|
||||
/** Returns the approximate number of operations in SkPicture. Returned value
|
||||
may be greater or less than the number of SkCanvas calls
|
||||
recorded: some calls may be recorded as more than one operation, other
|
||||
calls may be optimized away.
|
||||
|
||||
@param nested if true, include the op-counts of nested pictures as well, else
|
||||
just return count the ops in the top-level picture.
|
||||
@return approximate operation count
|
||||
|
||||
example: https://fiddle.skia.org/c/@Picture_approximateOpCount
|
||||
*/
|
||||
virtual int approximateOpCount(bool nested = false) const = 0;
|
||||
|
||||
/** Returns the approximate byte size of SkPicture. Does not include large objects
|
||||
referenced by SkPicture.
|
||||
|
||||
@return approximate size
|
||||
|
||||
example: https://fiddle.skia.org/c/@Picture_approximateBytesUsed
|
||||
*/
|
||||
virtual size_t approximateBytesUsed() const = 0;
|
||||
|
||||
/** Return a new shader that will draw with this picture.
|
||||
*
|
||||
* @param tmx The tiling mode to use when sampling in the x-direction.
|
||||
* @param tmy The tiling mode to use when sampling in the y-direction.
|
||||
* @param mode How to filter the tiles
|
||||
* @param localMatrix Optional matrix used when sampling
|
||||
* @param tileRect The tile rectangle in picture coordinates: this represents the subset
|
||||
* (or superset) of the picture used when building a tile. It is not
|
||||
* affected by localMatrix and does not imply scaling (only translation
|
||||
* and cropping). If null, the tile rect is considered equal to the picture
|
||||
* bounds.
|
||||
* @return Returns a new shader object. Note: this function never returns null.
|
||||
*/
|
||||
sk_sp<SkShader> makeShader(SkTileMode tmx, SkTileMode tmy, SkFilterMode mode,
|
||||
const SkMatrix* localMatrix, const SkRect* tileRect) const;
|
||||
|
||||
sk_sp<SkShader> makeShader(SkTileMode tmx, SkTileMode tmy, SkFilterMode mode) const {
|
||||
return this->makeShader(tmx, tmy, mode, nullptr, nullptr);
|
||||
}
|
||||
|
||||
private:
|
||||
// Allowed subclasses.
|
||||
SkPicture();
|
||||
friend class SkBigPicture;
|
||||
friend class SkEmptyPicture;
|
||||
friend class SkPicturePriv;
|
||||
|
||||
void serialize(SkWStream*, const SkSerialProcs*, class SkRefCntSet* typefaces,
|
||||
bool textBlobsOnly=false) const;
|
||||
static sk_sp<SkPicture> MakeFromStreamPriv(SkStream*, const SkDeserialProcs*,
|
||||
class SkTypefacePlayback*,
|
||||
int recursionLimit);
|
||||
friend class SkPictureData;
|
||||
|
||||
/** Return true if the SkStream/Buffer represents a serialized picture, and
|
||||
fills out SkPictInfo. After this function returns, the data source is not
|
||||
rewound so it will have to be manually reset before passing to
|
||||
MakeFromStream or MakeFromBuffer. Note, MakeFromStream and
|
||||
MakeFromBuffer perform this check internally so these entry points are
|
||||
intended for stand alone tools.
|
||||
If false is returned, SkPictInfo is unmodified.
|
||||
*/
|
||||
static bool StreamIsSKP(SkStream*, struct SkPictInfo*);
|
||||
static bool BufferIsSKP(class SkReadBuffer*, struct SkPictInfo*);
|
||||
friend bool SkPicture_StreamIsSKP(SkStream*, struct SkPictInfo*);
|
||||
|
||||
// Returns NULL if this is not an SkBigPicture.
|
||||
virtual const class SkBigPicture* asSkBigPicture() const { return nullptr; }
|
||||
|
||||
static bool IsValidPictInfo(const struct SkPictInfo& info);
|
||||
static sk_sp<SkPicture> Forwardport(const struct SkPictInfo&,
|
||||
const class SkPictureData*,
|
||||
class SkReadBuffer* buffer);
|
||||
|
||||
struct SkPictInfo createHeader() const;
|
||||
class SkPictureData* backport() const;
|
||||
|
||||
uint32_t fUniqueID;
|
||||
mutable std::atomic<bool> fAddedToCache{false};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* Copyright 2014 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkPictureRecorder_DEFINED
|
||||
#define SkPictureRecorder_DEFINED
|
||||
|
||||
#include "include/core/SkRect.h"
|
||||
#include "include/core/SkRefCnt.h"
|
||||
#include "include/core/SkScalar.h"
|
||||
#include "include/private/base/SkAPI.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
|
||||
namespace android {
|
||||
class Picture;
|
||||
};
|
||||
#endif
|
||||
|
||||
class SkBBHFactory;
|
||||
class SkBBoxHierarchy;
|
||||
class SkCanvas;
|
||||
class SkDrawable;
|
||||
class SkPicture;
|
||||
class SkRecord;
|
||||
class SkRecordCanvas;
|
||||
|
||||
class SK_API SkPictureRecorder {
|
||||
public:
|
||||
SkPictureRecorder();
|
||||
~SkPictureRecorder();
|
||||
|
||||
/** Returns the canvas that records the drawing commands.
|
||||
@param bounds the cull rect used when recording this picture. Any drawing the falls outside
|
||||
of this rect is undefined, and may be drawn or it may not.
|
||||
@param bbh optional acceleration structure
|
||||
@param recordFlags optional flags that control recording.
|
||||
@return the canvas.
|
||||
*/
|
||||
SkCanvas* beginRecording(const SkRect& bounds, sk_sp<SkBBoxHierarchy> bbh);
|
||||
|
||||
SkCanvas* beginRecording(const SkRect& bounds, SkBBHFactory* bbhFactory = nullptr);
|
||||
|
||||
SkCanvas* beginRecording(SkScalar width, SkScalar height,
|
||||
SkBBHFactory* bbhFactory = nullptr) {
|
||||
return this->beginRecording(SkRect::MakeWH(width, height), bbhFactory);
|
||||
}
|
||||
|
||||
/** Returns the recording canvas if one is active, or NULL if recording is
|
||||
not active. This does not alter the refcnt on the canvas (if present).
|
||||
*/
|
||||
SkCanvas* getRecordingCanvas();
|
||||
|
||||
/**
|
||||
* Signal that the caller is done recording. This invalidates the canvas returned by
|
||||
* beginRecording/getRecordingCanvas. Ownership of the object is passed to the caller, who
|
||||
* must call unref() when they are done using it.
|
||||
*
|
||||
* The returned picture is immutable. If during recording drawables were added to the canvas,
|
||||
* these will have been "drawn" into a recording canvas, so that this resulting picture will
|
||||
* reflect their current state, but will not contain a live reference to the drawables
|
||||
* themselves.
|
||||
*/
|
||||
sk_sp<SkPicture> finishRecordingAsPicture();
|
||||
|
||||
/**
|
||||
* Signal that the caller is done recording, and update the cull rect to use for bounding
|
||||
* box hierarchy (BBH) generation. The behavior is the same as calling
|
||||
* finishRecordingAsPicture(), except that this method updates the cull rect initially passed
|
||||
* into beginRecording.
|
||||
* @param cullRect the new culling rectangle to use as the overall bound for BBH generation
|
||||
* and subsequent culling operations.
|
||||
* @return the picture containing the recorded content.
|
||||
*/
|
||||
sk_sp<SkPicture> finishRecordingAsPictureWithCull(const SkRect& cullRect);
|
||||
|
||||
/**
|
||||
* Signal that the caller is done recording. This invalidates the canvas returned by
|
||||
* beginRecording/getRecordingCanvas. Ownership of the object is passed to the caller, who
|
||||
* must call unref() when they are done using it.
|
||||
*
|
||||
* Unlike finishRecordingAsPicture(), which returns an immutable picture, the returned drawable
|
||||
* may contain live references to other drawables (if they were added to the recording canvas)
|
||||
* 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->makePictureSnapshot()).
|
||||
*/
|
||||
sk_sp<SkDrawable> finishRecordingAsDrawable();
|
||||
|
||||
private:
|
||||
void reset();
|
||||
|
||||
/** Replay the current (partially recorded) operation stream into
|
||||
canvas. This call doesn't close the current recording.
|
||||
*/
|
||||
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
|
||||
friend class android::Picture;
|
||||
#endif
|
||||
friend class SkPictureRecorderReplayTester; // for unit testing
|
||||
void partialReplay(SkCanvas* canvas) const;
|
||||
|
||||
sk_sp<SkBBoxHierarchy> fBBH;
|
||||
std::unique_ptr<SkRecordCanvas> fRecorder;
|
||||
sk_sp<SkRecord> fRecord;
|
||||
SkRect fCullRect;
|
||||
bool fActivelyRecording;
|
||||
|
||||
SkPictureRecorder(SkPictureRecorder&&) = delete;
|
||||
SkPictureRecorder& operator=(SkPictureRecorder&&) = delete;
|
||||
};
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue