vendor: add Skia shared artifact

This commit is contained in:
abdussamedulutas 2026-07-28 17:50:35 +03:00
parent 719abce31e
commit d3d1643516
471 changed files with 493399 additions and 0 deletions

14
vendor/artifacts/skia/build/args.gn vendored Normal file
View File

@ -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

View File

@ -0,0 +1,5 @@
package(
default_applicable_licenses = ["//:license"],
)
licenses(["notice"])

16
vendor/artifacts/skia/include/OWNERS vendored Normal file
View File

@ -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

View File

@ -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

View File

@ -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",
],
)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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,
)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"],
)

View File

@ -0,0 +1,5 @@
module(
name = "skia_user_config",
)
bazel_dep(name = "rules_cc", version = "0.1.1")

View File

@ -0,0 +1,2 @@
bungeman@google.com
kjlubick@google.com

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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__"],
)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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_

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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