mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Back out changesets from bug 910754 due to build bustage
This commit is contained in:
parent
7c4ca1245a
commit
309648f662
@ -7,8 +7,7 @@
|
||||
#include "SourceSurfaceSkia.h"
|
||||
#include "ScaledFontBase.h"
|
||||
#include "ScaledFontCairo.h"
|
||||
#include "skia/SkGpuDevice.h"
|
||||
#include "skia/SkBitmapDevice.h"
|
||||
#include "skia/SkDevice.h"
|
||||
#include "FilterNodeSoftware.h"
|
||||
|
||||
#ifdef USE_SKIA_GPU
|
||||
@ -748,9 +747,9 @@ DrawTargetSkia::CopySurface(SourceSurface *aSurface,
|
||||
bool
|
||||
DrawTargetSkia::Init(const IntSize &aSize, SurfaceFormat aFormat)
|
||||
{
|
||||
SkAutoTUnref<SkBaseDevice> device(new SkBitmapDevice(GfxFormatToSkiaConfig(aFormat),
|
||||
aSize.width, aSize.height,
|
||||
aFormat == SurfaceFormat::B8G8R8X8));
|
||||
SkAutoTUnref<SkDevice> device(new SkDevice(GfxFormatToSkiaConfig(aFormat),
|
||||
aSize.width, aSize.height,
|
||||
aFormat == SurfaceFormat::B8G8R8X8));
|
||||
|
||||
SkBitmap bitmap = device->accessBitmap(true);
|
||||
if (!bitmap.allocPixels()) {
|
||||
@ -795,7 +794,7 @@ DrawTargetSkia::InitWithGLContextAndGrGLInterface(GenericRefCountedBase* aGLCont
|
||||
targetDescriptor.fRenderTargetHandle = 0; // GLContext always exposes the right framebuffer as id 0
|
||||
|
||||
SkAutoTUnref<GrRenderTarget> target(mGrContext->wrapBackendRenderTarget(targetDescriptor));
|
||||
SkAutoTUnref<SkBaseDevice> device(new SkGpuDevice(mGrContext.get(), target.get()));
|
||||
SkAutoTUnref<SkDevice> device(new SkGpuDevice(mGrContext.get(), target.get()));
|
||||
SkAutoTUnref<SkCanvas> canvas(new SkCanvas(device.get()));
|
||||
mCanvas = canvas.get();
|
||||
|
||||
@ -813,17 +812,18 @@ DrawTargetSkia::SetCacheLimits(int aCount, int aSizeInBytes)
|
||||
void
|
||||
DrawTargetSkia::Init(unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat)
|
||||
{
|
||||
SkAlphaType alphaType = kPremul_SkAlphaType;
|
||||
bool isOpaque = false;
|
||||
if (aFormat == SurfaceFormat::B8G8R8X8) {
|
||||
// We have to manually set the A channel to be 255 as Skia doesn't understand BGRX
|
||||
ConvertBGRXToBGRA(aData, aSize, aStride);
|
||||
alphaType = kOpaque_SkAlphaType;
|
||||
isOpaque = true;
|
||||
}
|
||||
|
||||
SkBitmap bitmap;
|
||||
bitmap.setConfig(GfxFormatToSkiaConfig(aFormat), aSize.width, aSize.height, aStride, alphaType);
|
||||
bitmap.setConfig(GfxFormatToSkiaConfig(aFormat), aSize.width, aSize.height, aStride);
|
||||
bitmap.setPixels(aData);
|
||||
SkAutoTUnref<SkCanvas> canvas(new SkCanvas(new SkBitmapDevice(bitmap)));
|
||||
bitmap.setIsOpaque(isOpaque);
|
||||
SkAutoTUnref<SkCanvas> canvas(new SkCanvas(new SkDevice(bitmap)));
|
||||
|
||||
mSize = aSize;
|
||||
mCanvas = canvas.get();
|
||||
|
@ -18,18 +18,19 @@ bool Scale(uint8_t* srcData, int32_t srcWidth, int32_t srcHeight, int32_t srcStr
|
||||
SurfaceFormat format)
|
||||
{
|
||||
#ifdef USE_SKIA
|
||||
SkAlphaType alphaType;
|
||||
bool opaque;
|
||||
if (format == SurfaceFormat::B8G8R8A8) {
|
||||
alphaType = kPremul_SkAlphaType;
|
||||
opaque = false;
|
||||
} else {
|
||||
alphaType = kOpaque_SkAlphaType;
|
||||
opaque = true;
|
||||
}
|
||||
|
||||
SkBitmap::Config config = GfxFormatToSkiaConfig(format);
|
||||
|
||||
SkBitmap imgSrc;
|
||||
imgSrc.setConfig(config, srcWidth, srcHeight, srcStride, alphaType);
|
||||
imgSrc.setConfig(config, srcWidth, srcHeight, srcStride);
|
||||
imgSrc.setPixels(srcData);
|
||||
imgSrc.setIsOpaque(opaque);
|
||||
|
||||
// Rescaler is compatible with 32 bpp only. Convert to RGB32 if needed.
|
||||
if (config != SkBitmap::kARGB_8888_Config) {
|
||||
|
@ -78,7 +78,7 @@ SourceSurfaceSkia::InitFromData(unsigned char* aData,
|
||||
ConvertBGRXToBGRA(reinterpret_cast<unsigned char*>(mBitmap.getPixels()), aSize, mBitmap.rowBytes());
|
||||
mBitmap.unlockPixels();
|
||||
mBitmap.notifyPixelsChanged();
|
||||
mBitmap.setAlphaType(kOpaque_SkAlphaType);
|
||||
mBitmap.setIsOpaque(true);
|
||||
}
|
||||
|
||||
mSize = aSize;
|
||||
|
@ -470,7 +470,7 @@ SkBitmap ImageOperations::ResizeSubpixel(const SkBitmap& source,
|
||||
src_row += h * row_words;
|
||||
dst_row += result.rowBytes() / 4;
|
||||
}
|
||||
result.setAlphaType(img.alphaType());
|
||||
result.setIsOpaque(img.isOpaque());
|
||||
return result;
|
||||
#else
|
||||
return SkBitmap();
|
||||
@ -534,7 +534,7 @@ SkBitmap ImageOperations::ResizeBasic(const SkBitmap& source,
|
||||
/* sse = */ false);
|
||||
|
||||
// Preserve the "opaque" flag for use as an optimization later.
|
||||
result.setAlphaType(source.alphaType());
|
||||
result.setIsOpaque(source.isOpaque());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -499,19 +499,6 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
|
||||
{ (PRFuncPtr*) &mSymbols.fUnmapBuffer, { "UnmapBuffer", nullptr } },
|
||||
{ (PRFuncPtr*) &mSymbols.fPointParameterf, { "PointParameterf", nullptr } },
|
||||
{ (PRFuncPtr*) &mSymbols.fDrawBuffer, { "DrawBuffer", nullptr } },
|
||||
// These functions are only used by Skia/GL in desktop mode.
|
||||
// Other parts of Gecko should avoid using these
|
||||
{ (PRFuncPtr*) &mSymbols.fDrawBuffers, { "DrawBuffers", nullptr } },
|
||||
{ (PRFuncPtr*) &mSymbols.fClientActiveTexture, { "ClientActiveTexture", nullptr } },
|
||||
{ (PRFuncPtr*) &mSymbols.fDisableClientState, { "DisableClientState", nullptr } },
|
||||
{ (PRFuncPtr*) &mSymbols.fEnableClientState, { "EnableClientState", nullptr } },
|
||||
{ (PRFuncPtr*) &mSymbols.fLoadIdentity, { "LoadIdentity", nullptr } },
|
||||
{ (PRFuncPtr*) &mSymbols.fLoadMatrixf, { "LoadMatrixf", nullptr } },
|
||||
{ (PRFuncPtr*) &mSymbols.fMatrixMode, { "MatrixMode", nullptr } },
|
||||
{ (PRFuncPtr*) &mSymbols.fTexGeni, { "TexGeni", nullptr } },
|
||||
{ (PRFuncPtr*) &mSymbols.fTexGenf, { "TexGenf", nullptr } },
|
||||
{ (PRFuncPtr*) &mSymbols.fTexGenfv, { "TexGenfv", nullptr } },
|
||||
{ (PRFuncPtr*) &mSymbols.fVertexPointer, { "VertexPointer", nullptr } },
|
||||
{ nullptr, { nullptr } },
|
||||
};
|
||||
|
||||
|
@ -862,12 +862,6 @@ public:
|
||||
AFTER_GL_CALL;
|
||||
}
|
||||
|
||||
void fClientActiveTexture(GLenum texture) {
|
||||
BEFORE_GL_CALL;
|
||||
mSymbols.fClientActiveTexture(texture);
|
||||
AFTER_GL_CALL;
|
||||
}
|
||||
|
||||
void fColorMask(realGLboolean red, realGLboolean green, realGLboolean blue, realGLboolean alpha) {
|
||||
BEFORE_GL_CALL;
|
||||
mSymbols.fColorMask(red, green, blue, alpha);
|
||||
@ -960,12 +954,6 @@ public:
|
||||
AFTER_GL_CALL;
|
||||
}
|
||||
|
||||
void fDisableClientState(GLenum capability) {
|
||||
BEFORE_GL_CALL;
|
||||
mSymbols.fDisableClientState(capability);
|
||||
AFTER_GL_CALL;
|
||||
}
|
||||
|
||||
void fDisableVertexAttribArray(GLuint index) {
|
||||
BEFORE_GL_CALL;
|
||||
mSymbols.fDisableVertexAttribArray(index);
|
||||
@ -1010,12 +998,6 @@ public:
|
||||
AFTER_GL_CALL;
|
||||
}
|
||||
|
||||
void fEnableClientState(GLenum capability) {
|
||||
BEFORE_GL_CALL;
|
||||
mSymbols.fEnableClientState(capability);
|
||||
AFTER_GL_CALL;
|
||||
}
|
||||
|
||||
void fEnableVertexAttribArray(GLuint index) {
|
||||
BEFORE_GL_CALL;
|
||||
mSymbols.fEnableVertexAttribArray(index);
|
||||
@ -1361,24 +1343,6 @@ public:
|
||||
AFTER_GL_CALL;
|
||||
}
|
||||
|
||||
void fLoadIdentity() {
|
||||
BEFORE_GL_CALL;
|
||||
mSymbols.fLoadIdentity();
|
||||
AFTER_GL_CALL;
|
||||
}
|
||||
|
||||
void fLoadMatrixf(const GLfloat *matrix) {
|
||||
BEFORE_GL_CALL;
|
||||
mSymbols.fLoadMatrixf(matrix);
|
||||
AFTER_GL_CALL;
|
||||
}
|
||||
|
||||
void fMatrixMode(GLenum mode) {
|
||||
BEFORE_GL_CALL;
|
||||
mSymbols.fMatrixMode(mode);
|
||||
AFTER_GL_CALL;
|
||||
}
|
||||
|
||||
void fPixelStorei(GLenum pname, GLint param) {
|
||||
BEFORE_GL_CALL;
|
||||
mSymbols.fPixelStorei(pname, param);
|
||||
@ -1506,24 +1470,6 @@ public:
|
||||
AFTER_GL_CALL;
|
||||
}
|
||||
|
||||
void fTexGeni(GLenum coord, GLenum pname, GLint param) {
|
||||
BEFORE_GL_CALL;
|
||||
mSymbols.fTexGeni(coord, pname, param);
|
||||
AFTER_GL_CALL;
|
||||
}
|
||||
|
||||
void fTexGenf(GLenum coord, GLenum pname, GLfloat param) {
|
||||
BEFORE_GL_CALL;
|
||||
mSymbols.fTexGenf(coord, pname, param);
|
||||
AFTER_GL_CALL;
|
||||
}
|
||||
|
||||
void fTexGenfv(GLenum coord, GLenum pname, const GLfloat *params) {
|
||||
BEFORE_GL_CALL;
|
||||
mSymbols.fTexGenfv(coord, pname, params);
|
||||
AFTER_GL_CALL;
|
||||
}
|
||||
|
||||
private:
|
||||
void raw_fTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) {
|
||||
BEFORE_GL_CALL;
|
||||
@ -1730,12 +1676,6 @@ public:
|
||||
AFTER_GL_CALL;
|
||||
}
|
||||
|
||||
void fVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer) {
|
||||
BEFORE_GL_CALL;
|
||||
mSymbols.fVertexPointer(size, type, stride, pointer);
|
||||
AFTER_GL_CALL;
|
||||
}
|
||||
|
||||
void fCompileShader(GLuint shader) {
|
||||
BEFORE_GL_CALL;
|
||||
mSymbols.fCompileShader(shader);
|
||||
|
@ -125,12 +125,6 @@ GrGLvoid glCompileShader_mozilla(GrGLuint shader)
|
||||
return sGLContext.get()->fCompileShader(shader);
|
||||
}
|
||||
|
||||
GrGLvoid glCopyTexSubImage2D_mozilla(GrGLenum target, GrGLint level, GrGLint xoffset, GrGLint yoffset,
|
||||
GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height)
|
||||
{
|
||||
return sGLContext.get()->fCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
|
||||
}
|
||||
|
||||
GrGLuint glCreateProgram_mozilla(void)
|
||||
{
|
||||
return sGLContext.get()->fCreateProgram();
|
||||
@ -256,11 +250,6 @@ GrGLvoid glGenTextures_mozilla(GrGLsizei n, GrGLuint* textures)
|
||||
return sGLContext.get()->fGenTextures(n, textures);
|
||||
}
|
||||
|
||||
GrGLvoid glGenerateMipmap_mozilla(GrGLenum target)
|
||||
{
|
||||
return sGLContext.get()->fGenerateMipmap(target);
|
||||
}
|
||||
|
||||
GrGLvoid glGetBufferParameteriv_mozilla(GrGLenum target, GrGLenum pname, GrGLint* params)
|
||||
{
|
||||
return sGLContext.get()->fGetBufferParameteriv(target, pname, params);
|
||||
@ -721,57 +710,6 @@ GrGLvoid glGenVertexArrays_mozilla(GrGLsizei n, GrGLuint *arrays) {
|
||||
return sGLContext.get()->fGenVertexArrays(n, arrays);
|
||||
}
|
||||
|
||||
// Additional functions required for desktop GL < version 3.2
|
||||
|
||||
GrGLvoid glClientActiveTexture_mozilla(GrGLenum texture)
|
||||
{
|
||||
return sGLContext.get()->fClientActiveTexture(texture);
|
||||
}
|
||||
|
||||
GrGLvoid glDisableClientState_mozilla(GrGLenum capability)
|
||||
{
|
||||
return sGLContext.get()->fDisableClientState(capability);
|
||||
}
|
||||
|
||||
GrGLvoid glEnableClientState_mozilla(GrGLenum capability)
|
||||
{
|
||||
return sGLContext.get()->fEnableClientState(capability);
|
||||
}
|
||||
|
||||
GrGLvoid glLoadMatrixf_mozilla(const GLfloat* matrix)
|
||||
{
|
||||
return sGLContext.get()->fLoadMatrixf(matrix);
|
||||
}
|
||||
|
||||
GrGLvoid glLoadIdentity_mozilla()
|
||||
{
|
||||
return sGLContext.get()->fLoadIdentity();
|
||||
}
|
||||
|
||||
GrGLvoid glMatrixMode_mozilla(GrGLenum mode)
|
||||
{
|
||||
return sGLContext.get()->fMatrixMode(mode);
|
||||
}
|
||||
|
||||
GrGLvoid glTexGeni_mozilla(GrGLenum coord, GrGLenum pname, GrGLint param)
|
||||
{
|
||||
return sGLContext.get()->fTexGeni(coord, pname, param);
|
||||
}
|
||||
|
||||
GrGLvoid glTexGenf_mozilla(GrGLenum coord, GrGLenum pname, GrGLfloat param)
|
||||
{
|
||||
return sGLContext.get()->fTexGenf(coord, pname, param);
|
||||
}
|
||||
|
||||
GrGLvoid glTexGenfv_mozilla(GrGLenum coord, GrGLenum pname, const GrGLfloat* param)
|
||||
{
|
||||
return sGLContext.get()->fTexGenfv(coord, pname, param);
|
||||
}
|
||||
|
||||
GrGLvoid glVertexPointer_mozilla(GrGLint size, GrGLenum type, GrGLsizei stride, const GrGLvoid* pointer)
|
||||
{
|
||||
return sGLContext.get()->fVertexPointer(size, type, stride, pointer);
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
@ -799,7 +737,6 @@ GrGLInterface* CreateGrGLInterfaceFromGLContext(GLContext* context)
|
||||
i->fClearStencil = glClearStencil_mozilla;
|
||||
i->fColorMask = glColorMask_mozilla;
|
||||
i->fCompileShader = glCompileShader_mozilla;
|
||||
i->fCopyTexSubImage2D = glCopyTexSubImage2D_mozilla;
|
||||
i->fCreateProgram = glCreateProgram_mozilla;
|
||||
i->fCreateShader = glCreateShader_mozilla;
|
||||
i->fCullFace = glCullFace_mozilla;
|
||||
@ -826,7 +763,6 @@ GrGLInterface* CreateGrGLInterfaceFromGLContext(GLContext* context)
|
||||
i->fGenRenderbuffers = glGenRenderbuffers_mozilla;
|
||||
i->fGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameteriv_mozilla;
|
||||
i->fGenTextures = glGenTextures_mozilla;
|
||||
i->fGenerateMipmap = glGenerateMipmap_mozilla;
|
||||
i->fGetBufferParameteriv = glGetBufferParameteriv_mozilla;
|
||||
i->fGetError = glGetError_mozilla;
|
||||
i->fGetIntegerv = glGetIntegerv_mozilla;
|
||||
@ -913,18 +849,6 @@ GrGLInterface* CreateGrGLInterfaceFromGLContext(GLContext* context)
|
||||
// Desktop OpenGL > 2.0
|
||||
i->fDrawBuffers = glDrawBuffers_mozilla;
|
||||
|
||||
// Desktop OpenGL < 3.2 (which we pretend to be)
|
||||
i->fClientActiveTexture = glClientActiveTexture_mozilla;
|
||||
i->fDisableClientState = glDisableClientState_mozilla;
|
||||
i->fEnableClientState = glEnableClientState_mozilla;
|
||||
i->fLoadIdentity = glLoadIdentity_mozilla;
|
||||
i->fLoadMatrixf = glLoadMatrixf_mozilla;
|
||||
i->fMatrixMode = glMatrixMode_mozilla;
|
||||
i->fTexGenf = glTexGenf_mozilla;
|
||||
i->fTexGenfv = glTexGenfv_mozilla;
|
||||
i->fTexGeni = glTexGeni_mozilla;
|
||||
i->fVertexPointer = glVertexPointer_mozilla;
|
||||
|
||||
// We support both desktop GL and GLES2
|
||||
if (context->IsGLES2()) {
|
||||
i->fBindingsExported = kES2_GrGLBinding;
|
||||
|
@ -313,31 +313,6 @@ struct GLContextSymbols
|
||||
typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGE) (GLenum target, GLenum internalFormat, GLsizei width, GLsizei height);
|
||||
PFNGLRENDERBUFFERSTORAGE fRenderbufferStorage;
|
||||
|
||||
// These functions are only used by Skia/GL in desktop mode.
|
||||
// Other parts of Gecko should avoid using these
|
||||
typedef void (GLAPIENTRY * PFNGLCLIENTACTIVETEXTURE) (GLenum texture);
|
||||
PFNGLCLIENTACTIVETEXTURE fClientActiveTexture;
|
||||
typedef void (GLAPIENTRY * PFNDISABLECLIENTSTATE) (GLenum capability);
|
||||
PFNDISABLECLIENTSTATE fDisableClientState;
|
||||
typedef void (GLAPIENTRY * PFNENABLECLIENTSTATE) (GLenum capability);
|
||||
PFNENABLECLIENTSTATE fEnableClientState;
|
||||
typedef void (GLAPIENTRY * PFNLOADIDENTITY) (void);
|
||||
PFNLOADIDENTITY fLoadIdentity;
|
||||
typedef void (GLAPIENTRY * PFNLOADMATRIXD) (const GLdouble* matrix);
|
||||
PFNLOADMATRIXD fLoadMatrixd;
|
||||
typedef void (GLAPIENTRY * PFNLOADMATRIXF) (const GLfloat* matrix);
|
||||
PFNLOADMATRIXF fLoadMatrixf;
|
||||
typedef void (GLAPIENTRY * PFNMATRIXMODE) (GLenum mode);
|
||||
PFNMATRIXMODE fMatrixMode;
|
||||
typedef void (GLAPIENTRY * PFNTEXGENI) (GLenum coord, GLenum pname, GLint param);
|
||||
PFNTEXGENI fTexGeni;
|
||||
typedef void (GLAPIENTRY * PFNTEXGENF) (GLenum coord, GLenum pname, GLfloat param);
|
||||
PFNTEXGENF fTexGenf;
|
||||
typedef void (GLAPIENTRY * PFNTEXGENFV) (GLenum coord, GLenum pname, const GLfloat* param);
|
||||
PFNTEXGENFV fTexGenfv;
|
||||
typedef void (GLAPIENTRY * PFNVERTEXPOINTER) (GLint size, GLenum type, GLsizei stride, const GLvoid* pointer);
|
||||
PFNVERTEXPOINTER fVertexPointer;
|
||||
|
||||
typedef void (GLAPIENTRY * PFNGLBLITFRAMEBUFFER) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
|
||||
PFNGLBLITFRAMEBUFFER fBlitFramebuffer;
|
||||
typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLE) (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height);
|
||||
|
@ -19,13 +19,10 @@ include $(topsrcdir)/config/rules.mk
|
||||
|
||||
ifneq (,$(INTEL_ARCHITECTURE))
|
||||
ifdef GNU_CC
|
||||
SkBitmapFilter_opts_SSE2.$(OBJ_SUFFIX): CXXFLAGS+=-msse2
|
||||
SkBitmapProcState_opts_SSE2.$(OBJ_SUFFIX): CXXFLAGS+=-msse2
|
||||
SkBitmapProcState_opts_SSSE3.$(OBJ_SUFFIX): CXXFLAGS+=-mssse3
|
||||
SkBlitRect_opts_SSE2.$(OBJ_SUFFIX): CXXFLAGS+=-msse2
|
||||
SkBlitRow_opts_SSE2.$(OBJ_SUFFIX): CXXFLAGS+=-msse2
|
||||
SkBlurImage_opts_SSE2.$(OBJ_SUFFIX): CXXFLAGS+=-msse2
|
||||
SkMorphology_opts_SSE2.$(OBJ_SUFFIX): CXXFLAGS+=-msse2
|
||||
SkBlitRect_opts_SSE2.$(OBJ_SUFFIX): CXXFLAGS+=-msse2
|
||||
SkUtils_opts_SSE2.$(OBJ_SUFFIX): CXXFLAGS+=-msse2
|
||||
endif
|
||||
endif
|
||||
|
@ -2,14 +2,4 @@ The source from this directory was copied from the skia subversion trunk
|
||||
using the update.sh script. The changes made were those applied by update.sh,
|
||||
the addition/update of Makefile.in files for the Mozilla build system.
|
||||
|
||||
The subversion revision used was r13424.
|
||||
|
||||
To update to a new version of Skia:
|
||||
|
||||
- Copy the entire trunk/ directory from a Skia clone to mozilla-central/gfx/skia
|
||||
- cd gfx/skia && ./gyp_mozbuild
|
||||
|
||||
Once that's done, use git status to view the files that have changed. Keep an eye on GrUserConfig.h
|
||||
and SkUserConfig.h as those probably don't want to be overwritten by upstream versions.
|
||||
|
||||
This process will be made more automatic in the future.
|
||||
The subversion revision used was r8495.
|
||||
|
@ -1,92 +0,0 @@
|
||||
# Copyright (c) 2012 Google Inc. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
import collections
|
||||
import os
|
||||
import gyp
|
||||
import gyp.common
|
||||
import gyp.msvs_emulation
|
||||
import json
|
||||
import sys
|
||||
|
||||
generator_supports_multiple_toolsets = True
|
||||
|
||||
generator_wants_static_library_dependencies_adjusted = False
|
||||
|
||||
generator_default_variables = {
|
||||
}
|
||||
for dirname in ['INTERMEDIATE_DIR', 'SHARED_INTERMEDIATE_DIR', 'PRODUCT_DIR',
|
||||
'LIB_DIR', 'SHARED_LIB_DIR']:
|
||||
# Some gyp steps fail if these are empty(!).
|
||||
generator_default_variables[dirname] = 'dir'
|
||||
for unused in ['RULE_INPUT_PATH', 'RULE_INPUT_ROOT', 'RULE_INPUT_NAME',
|
||||
'RULE_INPUT_DIRNAME', 'RULE_INPUT_EXT',
|
||||
'EXECUTABLE_PREFIX', 'EXECUTABLE_SUFFIX',
|
||||
'STATIC_LIB_PREFIX', 'STATIC_LIB_SUFFIX',
|
||||
'SHARED_LIB_PREFIX', 'SHARED_LIB_SUFFIX',
|
||||
'CONFIGURATION_NAME']:
|
||||
generator_default_variables[unused] = ''
|
||||
|
||||
|
||||
def CalculateVariables(default_variables, params):
|
||||
generator_flags = params.get('generator_flags', {})
|
||||
for key, val in generator_flags.items():
|
||||
default_variables.setdefault(key, val)
|
||||
default_variables.setdefault('OS', gyp.common.GetFlavor(params))
|
||||
|
||||
flavor = gyp.common.GetFlavor(params)
|
||||
if flavor =='win':
|
||||
# Copy additional generator configuration data from VS, which is shared
|
||||
# by the Windows Ninja generator.
|
||||
import gyp.generator.msvs as msvs_generator
|
||||
generator_additional_non_configuration_keys = getattr(msvs_generator,
|
||||
'generator_additional_non_configuration_keys', [])
|
||||
generator_additional_path_sections = getattr(msvs_generator,
|
||||
'generator_additional_path_sections', [])
|
||||
|
||||
gyp.msvs_emulation.CalculateCommonVariables(default_variables, params)
|
||||
|
||||
|
||||
def CalculateGeneratorInputInfo(params):
|
||||
"""Calculate the generator specific info that gets fed to input (called by
|
||||
gyp)."""
|
||||
generator_flags = params.get('generator_flags', {})
|
||||
if generator_flags.get('adjust_static_libraries', False):
|
||||
global generator_wants_static_library_dependencies_adjusted
|
||||
generator_wants_static_library_dependencies_adjusted = True
|
||||
|
||||
def GetOS(params):
|
||||
for d in params['defines']:
|
||||
pass
|
||||
|
||||
def GenerateOutput(target_list, target_dicts, data, params):
|
||||
# Map of target -> list of targets it depends on.
|
||||
edges = {}
|
||||
|
||||
# Queue of targets to visit.
|
||||
targets_to_visit = target_list[:]
|
||||
|
||||
sources = [];
|
||||
|
||||
while len(targets_to_visit) > 0:
|
||||
target = targets_to_visit.pop()
|
||||
if target in edges:
|
||||
continue
|
||||
edges[target] = []
|
||||
|
||||
target_sources = target_dicts[target].get('sources')
|
||||
if target_sources:
|
||||
for source in target_sources:
|
||||
if source.endswith('.cpp'):
|
||||
sources.append(source)
|
||||
|
||||
for dep in target_dicts[target].get('dependencies', []):
|
||||
edges[target].append(dep)
|
||||
targets_to_visit.append(dep)
|
||||
|
||||
skia_os = data['gyp/core.gyp']['variables']['skia_os%']
|
||||
|
||||
f = open('sources.json', 'w')
|
||||
json.dump(sources, f)
|
||||
f.close()
|
@ -1,295 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
|
||||
import locale
|
||||
locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
|
||||
|
||||
footer = """
|
||||
|
||||
# left out of UNIFIED_SOURCES for now; that's not C++ anyway, nothing else to unify it with
|
||||
if not CONFIG['INTEL_ARCHITECTURE'] and CONFIG['CPU_ARCH'] == 'arm' and CONFIG['GNU_CC']:
|
||||
SOURCES += [
|
||||
'trunk/src/opts/memset.arm.S',
|
||||
]
|
||||
|
||||
MSVC_ENABLE_PGO = True
|
||||
|
||||
FINAL_LIBRARY = 'gkmedias'
|
||||
LOCAL_INCLUDES += [
|
||||
'trunk/include/config',
|
||||
'trunk/include/core',
|
||||
'trunk/include/effects',
|
||||
'trunk/include/gpu',
|
||||
'trunk/include/images',
|
||||
'trunk/include/lazy',
|
||||
'trunk/include/pathops',
|
||||
'trunk/include/pipe',
|
||||
'trunk/include/ports',
|
||||
'trunk/include/utils',
|
||||
'trunk/include/utils/mac',
|
||||
'trunk/include/utils/win',
|
||||
'trunk/include/views',
|
||||
'trunk/src/core',
|
||||
'trunk/src/gpu',
|
||||
'trunk/src/gpu/effects',
|
||||
'trunk/src/gpu/gl',
|
||||
'trunk/src/image',
|
||||
'trunk/src/lazy',
|
||||
'trunk/src/opts',
|
||||
'trunk/src/sfnt',
|
||||
'trunk/src/utils',
|
||||
'trunk/src/utils/android',
|
||||
'trunk/src/utils/mac',
|
||||
'trunk/src/utils/win',
|
||||
]
|
||||
|
||||
DEFINES['SK_A32_SHIFT'] = 24
|
||||
DEFINES['SK_R32_SHIFT'] = 16
|
||||
DEFINES['SK_G32_SHIFT'] = 8
|
||||
DEFINES['SK_B32_SHIFT'] = 0
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gtk2', 'gtk3', 'gonk', 'cocoa'):
|
||||
DEFINES['SK_USE_POSIX_THREADS'] = 1
|
||||
|
||||
if CONFIG['INTEL_ARCHITECTURE'] and CONFIG['HAVE_TOOLCHAIN_SUPPORT_MSSSE3']:
|
||||
DEFINES['SK_BUILD_SSSE3'] = 1
|
||||
|
||||
if (CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android') or \
|
||||
(CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa') or \
|
||||
CONFIG['MOZ_WIDGET_GTK']:
|
||||
DEFINES['SK_FONTHOST_DOES_NOT_USE_FONTMGR'] = 1
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||
DEFINES['SKIA_DLL'] = 1
|
||||
|
||||
DEFINES['SKIA_IMPLEMENTATION'] = 1
|
||||
DEFINES['GR_IMPLEMENTATION'] = 1
|
||||
"""
|
||||
|
||||
import json
|
||||
|
||||
platforms = ['linux', 'mac', 'android', 'win']
|
||||
|
||||
custom_includes = {
|
||||
'trunk/src/ports/SkAtomics_android.h': True,
|
||||
'trunk/src/ports/SkAtomics_sync.h': True,
|
||||
'trunk/src/ports/SkAtomics_win.h': True,
|
||||
'trunk/src/ports/SkMutex_pthread.h': True,
|
||||
'trunk/src/ports/SkMutex_win.h': True
|
||||
}
|
||||
|
||||
def generate_includes():
|
||||
includes = {}
|
||||
for root, dirs, files in os.walk('trunk/include'):
|
||||
for name in files:
|
||||
if name.endswith('.h'):
|
||||
includes[os.path.join(root, name)] = True
|
||||
|
||||
return dict(includes.items() + custom_includes.items())
|
||||
|
||||
def generate_opt_sources():
|
||||
opt_sources = {'opts': {''}}
|
||||
for root, dirs, files in os.walk('trunk/src/opts'):
|
||||
for name in files:
|
||||
if name.endswith('.cpp'):
|
||||
opt_sources['opts'].add(os.path.join(root, name))
|
||||
|
||||
return opt_sources
|
||||
|
||||
def generate_platform_sources():
|
||||
sources = {}
|
||||
|
||||
for plat in platforms:
|
||||
if os.system("cd trunk && GYP_GENERATORS=dump_mozbuild ./gyp_skia -D OS=%s gyp/skia_lib.gyp" % plat) != 0:
|
||||
print 'Failed to generate sources for ' + plat
|
||||
continue
|
||||
|
||||
|
||||
f = open('trunk/sources.json');
|
||||
sources[plat] = set(json.load(f));
|
||||
f.close()
|
||||
|
||||
return dict(sources.items() + generate_opt_sources().items())
|
||||
|
||||
|
||||
def generate_separated_sources(platform_sources):
|
||||
blacklist = [
|
||||
'ChromeUtils',
|
||||
'SkImageDecoder_',
|
||||
'_gif',
|
||||
'SkFontConfigParser_android',
|
||||
'SkJpeg',
|
||||
'SkXML',
|
||||
'SkCity',
|
||||
'GrGLCreateNativeInterface',
|
||||
'fontconfig',
|
||||
'_neon',
|
||||
'SkImage_Codec',
|
||||
'SkBitmapChecksummer',
|
||||
'SkNativeGLContext',
|
||||
'SkFontConfig',
|
||||
'SkFontHost_win_dw',
|
||||
'SkForceLinking',
|
||||
'SkMovie',
|
||||
'SkImageDecoder',
|
||||
'SkImageEncoder',
|
||||
'SkBitmapHasher',
|
||||
'SkWGL',
|
||||
'SkImages',
|
||||
'SkDiscardableMemory_ashmem'
|
||||
]
|
||||
|
||||
def isblacklisted(value):
|
||||
for item in blacklist:
|
||||
if value.find(item) >= 0:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
separated = {
|
||||
'common': {
|
||||
#'trunk/src/effects/gradients/SkGradientTileProc.cpp',
|
||||
'trunk/src/gpu/gl/GrGLCreateNativeInterface_none.cpp',
|
||||
'trunk/src/ports/SkDiscardableMemory_none.cpp',
|
||||
'trunk/src/ports/SkImageDecoder_empty.cpp',
|
||||
# 'trunk/src/images/SkImages.cpp',
|
||||
# 'trunk/src/images/SkImageRef.cpp',
|
||||
# 'trunk/src/images/SkImageRef_GlobalPool.cpp',
|
||||
# 'trunk/src/images/SkImageRefPool.cpp',
|
||||
# 'trunk/src/images/SkImageDecoder.cpp',
|
||||
# 'trunk/src/images/SkImageDecoder_Factory.cpp',
|
||||
},
|
||||
'android': {
|
||||
# 'trunk/src/ports/SkDebug_android.cpp',
|
||||
'trunk/src/ports/SkFontHost_cairo.cpp',
|
||||
# 'trunk/src/ports/SkFontHost_FreeType.cpp',
|
||||
# 'trunk/src/ports/SkFontHost_FreeType_common.cpp',
|
||||
# 'trunk/src/ports/SkThread_pthread.cpp',
|
||||
# 'trunk/src/ports/SkPurgeableMemoryBlock_android.cpp',
|
||||
# 'trunk/src/ports/SkTime_Unix.cpp',
|
||||
# 'trunk/src/utils/SkThreadUtils_pthread.cpp',
|
||||
# 'trunk/src/utils/SkThreadUtils_pthread_other.cpp',
|
||||
# 'trunk/src/images/SkImageRef_ashmem.cpp',
|
||||
# 'trunk/src/utils/android/ashmem.cpp',
|
||||
},
|
||||
'linux': {
|
||||
'trunk/src/ports/SkFontHost_cairo.cpp',
|
||||
},
|
||||
'intel': {
|
||||
'trunk/src/opts/SkXfermode_opts_none.cpp',
|
||||
},
|
||||
'arm': {
|
||||
'trunk/src/opts/SkUtils_opts_arm.cpp',
|
||||
},
|
||||
'none': {
|
||||
'trunk/src/opts/SkUtils_opts_none.cpp',
|
||||
}
|
||||
}
|
||||
|
||||
for plat in platform_sources.keys():
|
||||
if not separated.has_key(plat):
|
||||
separated[plat] = set()
|
||||
|
||||
for value in platform_sources[plat]:
|
||||
if isblacklisted(value):
|
||||
continue
|
||||
|
||||
if value.find('_SSE') > 0 or value.find('_SSSE') > 0: #lol
|
||||
separated['intel'].add(value)
|
||||
continue
|
||||
|
||||
if value.find('_arm') > 0 or value.find('_neon') > 0:
|
||||
separated['arm'].add(value)
|
||||
continue
|
||||
|
||||
if value.find('_none') > 0:
|
||||
separated['none'].add(value)
|
||||
continue
|
||||
|
||||
found = True
|
||||
for other in platforms:
|
||||
if other == plat or not platform_sources.has_key(other):
|
||||
continue
|
||||
|
||||
if not value in platform_sources[other]:
|
||||
found = False
|
||||
break;
|
||||
|
||||
if found:
|
||||
separated['common'].add(value)
|
||||
else:
|
||||
separated[plat].add(value)
|
||||
|
||||
return separated
|
||||
|
||||
def uniq(seq):
|
||||
seen = set()
|
||||
seen_add = seen.add
|
||||
return [ x for x in seq if x not in seen and not seen_add(x)]
|
||||
|
||||
def write_list(f, name, values, indent):
|
||||
def write_indent(indent):
|
||||
for _ in range(indent):
|
||||
f.write(' ')
|
||||
|
||||
val_list = uniq(sorted(map(lambda val: val.replace('../', 'trunk/'), values), key=lambda x: x.lower()))
|
||||
|
||||
if len(val_list) == 0:
|
||||
return
|
||||
|
||||
write_indent(indent)
|
||||
f.write(name + ' += [\n')
|
||||
for val in val_list:
|
||||
write_indent(indent + 4)
|
||||
f.write('\'' + val + '\',\n')
|
||||
|
||||
write_indent(4)
|
||||
f.write(']\n')
|
||||
|
||||
def write_mozbuild(includes, sources):
|
||||
filename = 'moz.build'
|
||||
f = open(filename, 'w')
|
||||
|
||||
|
||||
write_list(f, 'EXPORTS.skia', includes, 0)
|
||||
|
||||
write_list(f, 'SOURCES', sources['common'], 0)
|
||||
|
||||
f.write("if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gonk'):\n")
|
||||
write_list(f, 'SOURCES', sources['android'], 4)
|
||||
|
||||
f.write("if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':\n")
|
||||
write_list(f, 'SOURCES', sources['mac'], 4)
|
||||
|
||||
f.write("if CONFIG['MOZ_WIDGET_GTK']:\n")
|
||||
write_list(f, 'SOURCES', sources['linux'], 4)
|
||||
|
||||
f.write("if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':\n")
|
||||
write_list(f, 'SOURCES', sources['win'], 4)
|
||||
|
||||
f.write("\n\n")
|
||||
f.write("if CONFIG['INTEL_ARCHITECTURE']:\n")
|
||||
write_list(f, 'SOURCES', sources['intel'], 4)
|
||||
|
||||
f.write("elif CONFIG['CPU_ARCH'] == 'arm' and CONFIG['GNU_CC']:\n")
|
||||
write_list(f, 'SOURCES', sources['arm'], 4)
|
||||
|
||||
f.write("else:\n")
|
||||
write_list(f, 'SOURCES', sources['none'], 4)
|
||||
|
||||
f.write(footer)
|
||||
|
||||
f.close()
|
||||
|
||||
print 'Wrote ' + filename
|
||||
|
||||
def main():
|
||||
includes = generate_includes()
|
||||
platform_sources = generate_platform_sources()
|
||||
separated_sources = generate_separated_sources(platform_sources)
|
||||
write_mozbuild(includes, separated_sources)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -1,13 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Install our generator
|
||||
cp dump_mozbuild.py trunk/third_party/externals/gyp/pylib/gyp/generator
|
||||
|
||||
# pushd trunk
|
||||
# for OS in win linux mac; do
|
||||
# GYP_GENERATORS=dump_mozbuild ./gyp_skia -D OS=$OS -D arm_neon=0 gyp/effects.gyp
|
||||
# done
|
||||
# popd
|
||||
|
||||
./generate_mozbuild.py
|
||||
|
@ -37,6 +37,22 @@
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/* Scalars (the fractional value type in skia) can be implemented either as
|
||||
floats or 16.16 integers (fixed). Exactly one of these two symbols must be
|
||||
defined.
|
||||
*/
|
||||
//#define SK_SCALAR_IS_FLOAT
|
||||
//#define SK_SCALAR_IS_FIXED
|
||||
|
||||
|
||||
/* For some performance-critical scalar operations, skia will optionally work
|
||||
around the standard float operators if it knows that the CPU does not have
|
||||
native support for floats. If your environment uses software floating point,
|
||||
define this flag.
|
||||
*/
|
||||
//#define SK_SOFTWARE_FLOAT
|
||||
|
||||
|
||||
/* 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
|
||||
@ -63,7 +79,7 @@
|
||||
allow instance count tracking in either debug or release builds. By
|
||||
default it is enabled in debug but disabled in release.
|
||||
*/
|
||||
#define SK_ENABLE_INST_COUNT 0
|
||||
//#define SK_ENABLE_INST_COUNT 1
|
||||
|
||||
/* If, in debugging mode, Skia needs to stop (presumably to invoke a debugger)
|
||||
it will call SK_CRASH(). If this is not defined it, it is defined in
|
||||
@ -88,6 +104,12 @@
|
||||
//#define SK_UINT8_BITFIELD_LENDIAN
|
||||
|
||||
|
||||
/* Some compilers don't support long long for 64bit integers. If yours does
|
||||
not, define this to the appropriate type.
|
||||
*/
|
||||
//#define SkLONGLONG int64_t
|
||||
|
||||
|
||||
/* 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
|
||||
@ -100,12 +122,10 @@
|
||||
*/
|
||||
//#define SK_DEFAULT_FONT_CACHE_LIMIT (1024 * 1024)
|
||||
|
||||
/*
|
||||
* 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)
|
||||
/* If defined, use CoreText instead of ATSUI on OS X.
|
||||
*/
|
||||
//#define SK_USE_MAC_CORE_TEXT
|
||||
|
||||
|
||||
/* If zlib is available and you want to support the flate compression
|
||||
algorithm (used in PDF generation), define SK_ZLIB_INCLUDE to be the
|
||||
@ -124,6 +144,17 @@
|
||||
*/
|
||||
//#define SK_SFNTLY_SUBSETTER "sfntly/subsetter/font_subsetter.h"
|
||||
|
||||
/* Define this to remove dimension checks on bitmaps. Not all blits will be
|
||||
correct yet, so this is mostly for debugging the implementation.
|
||||
*/
|
||||
#define SK_ALLOW_OVER_32K_BITMAPS
|
||||
|
||||
/**
|
||||
* To revert to int-only srcrect behavior in drawBitmapRect(ToRect),
|
||||
* define this symbol.
|
||||
*/
|
||||
//#define SK_SUPPORT_INT_SRCRECT_DRAWBITMAPRECT
|
||||
|
||||
/* 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
|
||||
@ -170,35 +201,14 @@
|
||||
*/
|
||||
//#define SK_SUPPORT_GPU 1
|
||||
|
||||
|
||||
/* The PDF generation code uses Path Ops to generate inverse fills and complex
|
||||
* clipping paths, but at this time, Path Ops is not release ready yet. So,
|
||||
* the code is hidden behind this #define guard. If you are feeling adventurous
|
||||
* and want the latest and greatest PDF generation code, uncomment the #define.
|
||||
* When Path Ops is release ready, the define guards and this user config
|
||||
* define should be removed entirely.
|
||||
/* Don't dither 32bit gradients, to match what the canvas test suite expects.
|
||||
*/
|
||||
//#define SK_PDF_USE_PATHOPS
|
||||
#define SK_DISABLE_DITHER_32BIT_GRADIENT
|
||||
|
||||
/* Skia uses these defines as the target of include preprocessor directives.
|
||||
* The header files pointed to by these defines provide declarations and
|
||||
* possibly inline implementations of threading primitives.
|
||||
*
|
||||
* See SkThread.h for documentation on what these includes must contain.
|
||||
/* Don't include stdint.h on windows as it conflicts with our build system.
|
||||
*/
|
||||
//#define SK_ATOMICS_PLATFORM_H "SkAtomics_xxx.h"
|
||||
//#define SK_MUTEX_PLATFORM_H "SkMutex_xxx.h"
|
||||
# if defined(SK_BUILD_FOR_WIN32)
|
||||
# define SK_ATOMICS_PLATFORM_H "skia/SkAtomics_win.h"
|
||||
# elif defined(SK_BUILD_FOR_ANDROID_FRAMEWORK)
|
||||
# define SK_ATOMICS_PLATFORM_H "skia/SkAtomics_android.h"
|
||||
# else
|
||||
# define SK_ATOMICS_PLATFORM_H "skia/SkAtomics_sync.h"
|
||||
# endif
|
||||
#ifdef SK_BUILD_FOR_WIN32
|
||||
#define SK_IGNORE_STDINT_DOT_H
|
||||
#endif
|
||||
|
||||
# if defined(SK_BUILD_FOR_WIN32)
|
||||
# define SK_MUTEX_PLATFORM_H "skia/SkMutex_win.h"
|
||||
# else
|
||||
# define SK_MUTEX_PLATFORM_H "skia/SkMutex_pthread.h"
|
||||
# endif
|
||||
#endif
|
23
gfx/skia/include/config/sk_stdint.h
Normal file
23
gfx/skia/include/config/sk_stdint.h
Normal file
@ -0,0 +1,23 @@
|
||||
|
||||
/*
|
||||
* 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 sk_stdint_DEFINED
|
||||
#define sk_stdint_DEFINED
|
||||
|
||||
typedef signed char int8_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef short int16_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef int int32_t;
|
||||
typedef unsigned uint32_t;
|
||||
typedef long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
|
||||
typedef int64_t intmax_t;
|
||||
typedef uint64_t uintmax_t;
|
||||
|
||||
#endif
|
@ -15,6 +15,7 @@
|
||||
#include "SkString.h"
|
||||
#include "SkTDArray.h"
|
||||
#include "SkTemplates.h"
|
||||
#include "SkTScopedPtr.h"
|
||||
|
||||
/** \class SkAdvancedTypefaceMetrics
|
||||
|
||||
@ -89,7 +90,7 @@ public:
|
||||
uint16_t fStartId;
|
||||
uint16_t fEndId;
|
||||
SkTDArray<Data> fAdvance;
|
||||
SkAutoTDelete<AdvanceMetric<Data> > fNext;
|
||||
SkTScopedPtr<AdvanceMetric<Data> > fNext;
|
||||
};
|
||||
|
||||
struct VerticalMetric {
|
||||
@ -101,12 +102,12 @@ public:
|
||||
typedef AdvanceMetric<VerticalMetric> VerticalAdvanceRange;
|
||||
|
||||
// This is indexed by glyph id.
|
||||
SkAutoTDelete<WidthRange> fGlyphWidths;
|
||||
SkTScopedPtr<WidthRange> fGlyphWidths;
|
||||
// Only used for Vertical CID fonts.
|
||||
SkAutoTDelete<VerticalAdvanceRange> fVerticalMetrics;
|
||||
SkTScopedPtr<VerticalAdvanceRange> fVerticalMetrics;
|
||||
|
||||
// The names of each glyph, only populated for postscript fonts.
|
||||
SkAutoTDelete<SkAutoTArray<SkString> > fGlyphNames;
|
||||
SkTScopedPtr<SkAutoTArray<SkString> > fGlyphNames;
|
||||
|
||||
// The mapping from glyph to Unicode, only populated if
|
||||
// kToUnicode_PerGlyphInfo is passed to GetAdvancedTypefaceMetrics.
|
||||
@ -124,7 +125,7 @@ void resetRange(SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range,
|
||||
|
||||
template <typename Data>
|
||||
SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* appendRange(
|
||||
SkAutoTDelete<SkAdvancedTypefaceMetrics::AdvanceMetric<Data> >* nextSlot,
|
||||
SkTScopedPtr<SkAdvancedTypefaceMetrics::AdvanceMetric<Data> >* nextSlot,
|
||||
int startId);
|
||||
|
||||
template <typename Data>
|
@ -8,12 +8,10 @@
|
||||
#ifndef SkAnnotation_DEFINED
|
||||
#define SkAnnotation_DEFINED
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkString.h"
|
||||
#include "SkFlattenable.h"
|
||||
|
||||
class SkData;
|
||||
class SkReadBuffer;
|
||||
class SkWriteBuffer;
|
||||
class SkDataSet;
|
||||
class SkStream;
|
||||
class SkWStream;
|
||||
struct SkPoint;
|
||||
@ -22,24 +20,40 @@ struct SkPoint;
|
||||
* Experimental class for annotating draws. Do not use directly yet.
|
||||
* Use helper functions at the bottom of this file for now.
|
||||
*/
|
||||
class SkAnnotation : public SkRefCnt {
|
||||
class SkAnnotation : public SkFlattenable {
|
||||
public:
|
||||
SkAnnotation(const char key[], SkData* value);
|
||||
enum Flags {
|
||||
// If set, the associated drawing primitive should not be drawn
|
||||
kNoDraw_Flag = 1 << 0,
|
||||
};
|
||||
|
||||
SkAnnotation(SkDataSet*, uint32_t flags);
|
||||
virtual ~SkAnnotation();
|
||||
|
||||
/**
|
||||
* Return the data for the specified key, or NULL.
|
||||
*/
|
||||
SkData* find(const char key[]) const;
|
||||
uint32_t getFlags() const { return fFlags; }
|
||||
SkDataSet* getDataSet() const { return fDataSet; }
|
||||
|
||||
SkAnnotation(SkReadBuffer&);
|
||||
void writeToBuffer(SkWriteBuffer&) const;
|
||||
bool isNoDraw() const { return SkToBool(fFlags & kNoDraw_Flag); }
|
||||
|
||||
/**
|
||||
* Helper for search the annotation's dataset.
|
||||
*/
|
||||
SkData* find(const char name[]) const;
|
||||
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkAnnotation)
|
||||
|
||||
protected:
|
||||
SkAnnotation(SkFlattenableReadBuffer&);
|
||||
virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
SkString fKey;
|
||||
SkData* fData;
|
||||
SkDataSet* fDataSet;
|
||||
uint32_t fFlags;
|
||||
|
||||
typedef SkRefCnt INHERITED;
|
||||
void writeToStream(SkWStream*) const;
|
||||
void readFromStream(SkStream*);
|
||||
|
||||
typedef SkFlattenable INHERITED;
|
||||
};
|
||||
|
||||
/**
|
@ -1,3 +1,4 @@
|
||||
|
||||
/*
|
||||
* Copyright 2006 The Android Open Source Project
|
||||
*
|
||||
@ -5,12 +6,13 @@
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SkBitmap_DEFINED
|
||||
#define SkBitmap_DEFINED
|
||||
|
||||
#include "Sk64.h"
|
||||
#include "SkColor.h"
|
||||
#include "SkColorTable.h"
|
||||
#include "SkImageInfo.h"
|
||||
#include "SkPoint.h"
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
@ -18,11 +20,11 @@ struct SkIRect;
|
||||
struct SkRect;
|
||||
class SkPaint;
|
||||
class SkPixelRef;
|
||||
class SkPixelRefFactory;
|
||||
class SkRegion;
|
||||
class SkString;
|
||||
|
||||
class GrTexture;
|
||||
// This is an opaque class, not interpreted by skia
|
||||
class SkGpuTexture;
|
||||
|
||||
/** \class SkBitmap
|
||||
|
||||
@ -36,21 +38,29 @@ class GrTexture;
|
||||
*/
|
||||
class SK_API SkBitmap {
|
||||
public:
|
||||
class SK_API Allocator;
|
||||
class Allocator;
|
||||
|
||||
enum Config {
|
||||
kNo_Config, //!< bitmap has not been configured
|
||||
/**
|
||||
* 1-bit per pixel, (0 is transparent, 1 is opaque)
|
||||
* Valid as a destination (target of a canvas), but not valid as a src.
|
||||
* i.e. you can draw into a 1-bit bitmap, but you cannot draw from one.
|
||||
*/
|
||||
kA1_Config,
|
||||
kA8_Config, //!< 8-bits per pixel, with only alpha specified (0 is transparent, 0xFF is opaque)
|
||||
kIndex8_Config, //!< 8-bits per pixel, using SkColorTable to specify the colors
|
||||
kRGB_565_Config, //!< 16-bits per pixel, (see SkColorPriv.h for packing)
|
||||
kARGB_4444_Config, //!< 16-bits per pixel, (see SkColorPriv.h for packing)
|
||||
kARGB_8888_Config, //!< 32-bits per pixel, (see SkColorPriv.h for packing)
|
||||
};
|
||||
/**
|
||||
* Custom compressed format, not supported on all platforms.
|
||||
* Cannot be used as a destination (target of a canvas).
|
||||
* i.e. you may be able to draw from one, but you cannot draw into one.
|
||||
*/
|
||||
kRLE_Index8_Config,
|
||||
|
||||
// do not add this to the Config enum, otherwise the compiler will let us
|
||||
// pass this as a valid parameter for Config.
|
||||
enum {
|
||||
kConfigCount = kARGB_8888_Config + 1
|
||||
kConfigCount
|
||||
};
|
||||
|
||||
/**
|
||||
@ -79,72 +89,49 @@ public:
|
||||
// This method is not exported to java.
|
||||
void swap(SkBitmap& other);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const SkImageInfo& info() const { return fInfo; }
|
||||
|
||||
int width() const { return fInfo.fWidth; }
|
||||
int height() const { return fInfo.fHeight; }
|
||||
SkColorType colorType() const { return fInfo.fColorType; }
|
||||
SkAlphaType alphaType() const { return fInfo.fAlphaType; }
|
||||
|
||||
/** Return the number of bytes per pixel based on the config. If the config
|
||||
does not have at least 1 byte per (e.g. kA1_Config) then 0 is returned.
|
||||
*/
|
||||
int bytesPerPixel() const { return fInfo.bytesPerPixel(); }
|
||||
|
||||
/** Return the rowbytes expressed as a number of pixels (like width and
|
||||
height). Note, for 1-byte per pixel configs like kA8_Config, this will
|
||||
return the same as rowBytes(). Is undefined for configs that are less
|
||||
than 1-byte per pixel (e.g. kA1_Config)
|
||||
*/
|
||||
int rowBytesAsPixels() const {
|
||||
return fRowBytes >> this->shiftPerPixel();
|
||||
}
|
||||
|
||||
/** Return the shift amount per pixel (i.e. 0 for 1-byte per pixel, 1 for
|
||||
2-bytes per pixel configs, 2 for 4-bytes per pixel configs). Return 0
|
||||
for configs that are not at least 1-byte per pixel (e.g. kA1_Config
|
||||
or kNo_Config)
|
||||
*/
|
||||
int shiftPerPixel() const { return this->bytesPerPixel() >> 1; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Return true iff the bitmap has empty dimensions.
|
||||
* Hey! Before you use this, see if you really want to know drawsNothing() instead.
|
||||
*/
|
||||
bool empty() const { return fInfo.isEmpty(); }
|
||||
*/
|
||||
bool empty() const { return 0 == fWidth || 0 == fHeight; }
|
||||
|
||||
/** Return true iff the bitmap has no pixelref. Note: this can return true even if the
|
||||
* dimensions of the bitmap are > 0 (see empty()).
|
||||
* Hey! Before you use this, see if you really want to know drawsNothing() instead.
|
||||
*/
|
||||
dimensions of the bitmap are > 0 (see empty()).
|
||||
*/
|
||||
bool isNull() const { return NULL == fPixelRef; }
|
||||
|
||||
/** Return true iff drawing this bitmap has no effect.
|
||||
*/
|
||||
bool drawsNothing() const { return this->empty() || this->isNull(); }
|
||||
|
||||
/** Return the config for the bitmap. */
|
||||
Config config() const;
|
||||
|
||||
SK_ATTR_DEPRECATED("use config()")
|
||||
/** Return the config for the bitmap.
|
||||
*/
|
||||
Config config() const { return (Config)fConfig; }
|
||||
/** DEPRECATED, use config()
|
||||
*/
|
||||
Config getConfig() const { return this->config(); }
|
||||
|
||||
/** Return the number of bytes between subsequent rows of the bitmap. */
|
||||
/** Return the bitmap's width, in pixels.
|
||||
*/
|
||||
int width() const { return fWidth; }
|
||||
/** Return the bitmap's height, in pixels.
|
||||
*/
|
||||
int height() const { return fHeight; }
|
||||
/** Return the number of bytes between subsequent rows of the bitmap.
|
||||
*/
|
||||
size_t rowBytes() const { return fRowBytes; }
|
||||
|
||||
/**
|
||||
* Set the bitmap's alphaType, returning true on success. If false is
|
||||
* returned, then the specified new alphaType is incompatible with the
|
||||
* Config, and the current alphaType is unchanged.
|
||||
*
|
||||
* Note: this changes the alphatype for the underlying pixels, which means
|
||||
* that all bitmaps that might be sharing (subsets of) the pixels will
|
||||
* be affected.
|
||||
*/
|
||||
bool setAlphaType(SkAlphaType);
|
||||
/** Return the shift amount per pixel (i.e. 0 for 1-byte per pixel, 1 for
|
||||
2-bytes per pixel configs, 2 for 4-bytes per pixel configs). Return 0
|
||||
for configs that are not at least 1-byte per pixel (e.g. kA1_Config
|
||||
or kNo_Config)
|
||||
*/
|
||||
int shiftPerPixel() const { return fBytesPerPixel >> 1; }
|
||||
|
||||
/** Return the number of bytes per pixel based on the config. If the config
|
||||
does not have at least 1 byte per (e.g. kA1_Config) then 0 is returned.
|
||||
*/
|
||||
int bytesPerPixel() const { return fBytesPerPixel; }
|
||||
|
||||
/** Return the rowbytes expressed as a number of pixels (like width and
|
||||
height). Note, for 1-byte per pixel configs like kA8_Config, this will
|
||||
return the same as rowBytes(). Is undefined for configs that are less
|
||||
than 1-byte per pixel (e.g. kA1_Config)
|
||||
*/
|
||||
int rowBytesAsPixels() const { return fRowBytes >> (fBytesPerPixel >> 1); }
|
||||
|
||||
/** Return the address of the pixels for this SkBitmap.
|
||||
*/
|
||||
@ -154,29 +141,27 @@ public:
|
||||
Note this truncates the result to 32bits. Call getSize64() to detect
|
||||
if the real size exceeds 32bits.
|
||||
*/
|
||||
size_t getSize() const { return fInfo.fHeight * fRowBytes; }
|
||||
size_t getSize() const { return fHeight * fRowBytes; }
|
||||
|
||||
/** Return the number of bytes from the pointer returned by getPixels()
|
||||
to the end of the allocated space in the buffer. Required in
|
||||
cases where extractSubset has been called.
|
||||
*/
|
||||
size_t getSafeSize() const { return fInfo.getSafeSize(fRowBytes); }
|
||||
size_t getSafeSize() const ;
|
||||
|
||||
/**
|
||||
* Return the full size of the bitmap, in bytes.
|
||||
*/
|
||||
int64_t computeSize64() const {
|
||||
return sk_64_mul(fInfo.fHeight, fRowBytes);
|
||||
/** Return the byte size of the pixels, based on the height and rowBytes.
|
||||
This routine is slightly slower than getSize(), but does not truncate
|
||||
the answer to 32bits.
|
||||
*/
|
||||
Sk64 getSize64() const {
|
||||
Sk64 size;
|
||||
size.setMul(fHeight, fRowBytes);
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of bytes from the pointer returned by getPixels()
|
||||
* to the end of the allocated space in the buffer. This may be smaller
|
||||
* than computeSize64() if there is any rowbytes padding beyond the width.
|
||||
*/
|
||||
int64_t computeSafeSize64() const {
|
||||
return fInfo.getSafeSize64(fRowBytes);
|
||||
}
|
||||
/** Same as getSafeSize(), but does not truncate the answer to 32bits.
|
||||
*/
|
||||
Sk64 getSafeSize64() const ;
|
||||
|
||||
/** Returns true if this bitmap is marked as immutable, meaning that the
|
||||
contents of its pixels will not change for the lifetime of the bitmap.
|
||||
@ -193,9 +178,12 @@ public:
|
||||
|
||||
/** Returns true if the bitmap is opaque (has no translucent/transparent pixels).
|
||||
*/
|
||||
bool isOpaque() const {
|
||||
return SkAlphaTypeIsOpaque(this->alphaType());
|
||||
}
|
||||
bool isOpaque() const;
|
||||
|
||||
/** Specify if this bitmap's pixels are all opaque or not. Is only meaningful for configs
|
||||
that support per-pixel alpha (RGB32, A1, A8).
|
||||
*/
|
||||
void setIsOpaque(bool);
|
||||
|
||||
/** Returns true if the bitmap is volatile (i.e. should not be cached by devices.)
|
||||
*/
|
||||
@ -232,7 +220,7 @@ public:
|
||||
return ComputeBytesPerPixel(c) >> 1;
|
||||
}
|
||||
|
||||
static int64_t ComputeSize64(Config, int width, int height);
|
||||
static Sk64 ComputeSize64(Config, int width, int height);
|
||||
static size_t ComputeSize(Config, int width, int height);
|
||||
|
||||
/**
|
||||
@ -241,11 +229,18 @@ public:
|
||||
* it will return false.
|
||||
*
|
||||
* Since this can be an expensive operation, the bitmap stores a flag for
|
||||
* this (isOpaque). Only call this if you need to compute this value from
|
||||
* "unknown" pixels.
|
||||
* this (isOpaque, setIsOpaque). Only call this if you need to compute this
|
||||
* value from "unknown" pixels.
|
||||
*/
|
||||
static bool ComputeIsOpaque(const SkBitmap&);
|
||||
|
||||
/**
|
||||
* Calls ComputeIsOpaque, and passes its result to setIsOpaque().
|
||||
*/
|
||||
void computeAndSetOpaquePredicate() {
|
||||
this->setIsOpaque(ComputeIsOpaque(*this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the bitmap's bounds [0, 0, width, height] as an SkRect
|
||||
*/
|
||||
@ -256,72 +251,7 @@ public:
|
||||
ComputeRowBytes() is called to compute the optimal value. This resets
|
||||
any pixel/colortable ownership, just like reset().
|
||||
*/
|
||||
bool setConfig(Config, int width, int height, size_t rowBytes, SkAlphaType);
|
||||
|
||||
bool setConfig(Config config, int width, int height, size_t rowBytes = 0) {
|
||||
return this->setConfig(config, width, height, rowBytes,
|
||||
kPremul_SkAlphaType);
|
||||
}
|
||||
|
||||
bool setConfig(const SkImageInfo& info, size_t rowBytes = 0);
|
||||
|
||||
/**
|
||||
* Allocate a pixelref to match the specified image info. If the Factory
|
||||
* is non-null, call it to allcoate the pixelref. If the ImageInfo requires
|
||||
* a colortable, then ColorTable must be non-null, and will be ref'd.
|
||||
* On failure, the bitmap will be set to empty and return false.
|
||||
*/
|
||||
bool allocPixels(const SkImageInfo&, SkPixelRefFactory*, SkColorTable*);
|
||||
|
||||
/**
|
||||
* Allocate a pixelref to match the specified image info, using the default
|
||||
* allocator.
|
||||
* On success, the bitmap's pixels will be "locked", and return true.
|
||||
* On failure, the bitmap will be set to empty and return false.
|
||||
*/
|
||||
bool allocPixels(const SkImageInfo& info) {
|
||||
return this->allocPixels(info, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legacy helper function, which creates an SkImageInfo from the specified
|
||||
* config and then calls allocPixels(info).
|
||||
*/
|
||||
bool allocConfigPixels(Config, int width, int height, bool isOpaque = false);
|
||||
|
||||
bool allocN32Pixels(int width, int height, bool isOpaque = false) {
|
||||
SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
|
||||
if (isOpaque) {
|
||||
info.fAlphaType = kOpaque_SkAlphaType;
|
||||
}
|
||||
return this->allocPixels(info);
|
||||
}
|
||||
|
||||
/**
|
||||
* Install a pixelref that wraps the specified pixels and rowBytes, and
|
||||
* optional ReleaseProc and context. When the pixels are no longer
|
||||
* referenced, if ReleaseProc is not null, it will be called with the
|
||||
* pixels and context as parameters.
|
||||
* On failure, the bitmap will be set to empty and return false.
|
||||
*/
|
||||
bool installPixels(const SkImageInfo&, void* pixels, size_t rowBytes,
|
||||
void (*ReleaseProc)(void* addr, void* context),
|
||||
void* context);
|
||||
|
||||
/**
|
||||
* DEPRECATED: call info().
|
||||
*/
|
||||
bool asImageInfo(SkImageInfo* info) const {
|
||||
// compatibility: return false for kUnknown
|
||||
if (kUnknown_SkColorType == this->colorType()) {
|
||||
return false;
|
||||
}
|
||||
if (info) {
|
||||
*info = this->info();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void setConfig(Config, int width, int height, size_t rowBytes = 0);
|
||||
/** Use this to assign a new pixel address for an existing bitmap. This
|
||||
will automatically release any pixelref previously installed. Only call
|
||||
this if you are handling ownership/lifetime of the pixel memory.
|
||||
@ -393,41 +323,18 @@ public:
|
||||
*/
|
||||
bool allocPixels(Allocator* allocator, SkColorTable* ctable);
|
||||
|
||||
/**
|
||||
* Return the current pixelref object or NULL if there is none. This does
|
||||
* not affect the refcount of the pixelref.
|
||||
*/
|
||||
/** Return the current pixelref object, if any
|
||||
*/
|
||||
SkPixelRef* pixelRef() const { return fPixelRef; }
|
||||
|
||||
/**
|
||||
* A bitmap can reference a subset of a pixelref's pixels. That means the
|
||||
* bitmap's width/height can be <= the dimensions of the pixelref. The
|
||||
* pixelref origin is the x,y location within the pixelref's pixels for
|
||||
* the bitmap's top/left corner. To be valid the following must be true:
|
||||
*
|
||||
* origin_x + bitmap_width <= pixelref_width
|
||||
* origin_y + bitmap_height <= pixelref_height
|
||||
*
|
||||
* pixelRefOrigin() returns this origin, or (0,0) if there is no pixelRef.
|
||||
*/
|
||||
SkIPoint pixelRefOrigin() const { return fPixelRefOrigin; }
|
||||
|
||||
/**
|
||||
* Assign a pixelref and origin to the bitmap. Pixelrefs are reference,
|
||||
* so the existing one (if any) will be unref'd and the new one will be
|
||||
* ref'd. (x,y) specify the offset within the pixelref's pixels for the
|
||||
* top/left corner of the bitmap. For a bitmap that encompases the entire
|
||||
* pixels of the pixelref, these will be (0,0).
|
||||
*/
|
||||
SkPixelRef* setPixelRef(SkPixelRef* pr, int dx, int dy);
|
||||
|
||||
SkPixelRef* setPixelRef(SkPixelRef* pr, const SkIPoint& origin) {
|
||||
return this->setPixelRef(pr, origin.fX, origin.fY);
|
||||
}
|
||||
|
||||
SkPixelRef* setPixelRef(SkPixelRef* pr) {
|
||||
return this->setPixelRef(pr, 0, 0);
|
||||
}
|
||||
/** Return the offset into the pixelref, if any. Will return 0 if there is
|
||||
no pixelref installed.
|
||||
*/
|
||||
size_t pixelRefOffset() const { return fPixelRefOffset; }
|
||||
/** Assign a pixelref and optional offset. Pixelrefs are reference counted,
|
||||
so the existing one (if any) will be unref'd and the new one will be
|
||||
ref'd.
|
||||
*/
|
||||
SkPixelRef* setPixelRef(SkPixelRef* pr, size_t offset = 0);
|
||||
|
||||
/** Call this to ensure that the bitmap points to the current pixel address
|
||||
in the pixelref. Balance it with a call to unlockPixels(). These calls
|
||||
@ -455,16 +362,16 @@ public:
|
||||
*/
|
||||
bool readyToDraw() const {
|
||||
return this->getPixels() != NULL &&
|
||||
(this->config() != kIndex8_Config || NULL != fColorTable);
|
||||
((this->config() != kIndex8_Config &&
|
||||
this->config() != kRLE_Index8_Config) ||
|
||||
fColorTable != NULL);
|
||||
}
|
||||
|
||||
/** Returns the pixelRef's texture, or NULL
|
||||
*/
|
||||
GrTexture* getTexture() const;
|
||||
SkGpuTexture* getTexture() const;
|
||||
|
||||
/** Return the bitmap's colortable, if it uses one (i.e. colorType is
|
||||
Index_8) and the pixels are locked.
|
||||
Otherwise returns NULL. Does not affect the colortable's
|
||||
/** Return the bitmap's colortable (if any). Does not affect the colortable's
|
||||
reference count.
|
||||
*/
|
||||
SkColorTable* getColorTable() const { return fColorTable; }
|
||||
@ -482,38 +389,28 @@ public:
|
||||
*/
|
||||
void notifyPixelsChanged() const;
|
||||
|
||||
/**
|
||||
* Fill the entire bitmap with the specified color.
|
||||
* If the bitmap's config does not support alpha (e.g. 565) then the alpha
|
||||
* of the color is ignored (treated as opaque). If the config only supports
|
||||
* alpha (e.g. A1 or A8) then the color's r,g,b components are ignored.
|
||||
*/
|
||||
/** Initialize the bitmap's pixels with the specified color+alpha, automatically converting into the correct format
|
||||
for the bitmap's config. If the config is kRGB_565_Config, then the alpha value is ignored.
|
||||
If the config is kA8_Config, then the r,g,b parameters are ignored.
|
||||
*/
|
||||
void eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const;
|
||||
/** Initialize the bitmap's pixels with the specified color+alpha, automatically converting into the correct format
|
||||
for the bitmap's config. If the config is kRGB_565_Config, then the alpha value is presumed
|
||||
to be 0xFF. If the config is kA8_Config, then the r,g,b parameters are ignored and the
|
||||
pixels are all set to 0xFF.
|
||||
*/
|
||||
void eraseRGB(U8CPU r, U8CPU g, U8CPU b) const {
|
||||
this->eraseARGB(0xFF, r, g, b);
|
||||
}
|
||||
/** Initialize the bitmap's pixels with the specified color, automatically converting into the correct format
|
||||
for the bitmap's config. If the config is kRGB_565_Config, then the color's alpha value is presumed
|
||||
to be 0xFF. If the config is kA8_Config, then only the color's alpha value is used.
|
||||
*/
|
||||
void eraseColor(SkColor c) const {
|
||||
this->eraseARGB(SkColorGetA(c), SkColorGetR(c), SkColorGetG(c),
|
||||
SkColorGetB(c));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the entire bitmap with the specified color.
|
||||
* If the bitmap's config does not support alpha (e.g. 565) then the alpha
|
||||
* of the color is ignored (treated as opaque). If the config only supports
|
||||
* alpha (e.g. A1 or A8) then the color's r,g,b components are ignored.
|
||||
*/
|
||||
void eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const;
|
||||
|
||||
SK_ATTR_DEPRECATED("use eraseARGB or eraseColor")
|
||||
void eraseRGB(U8CPU r, U8CPU g, U8CPU b) const {
|
||||
this->eraseARGB(0xFF, r, g, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the specified area of this bitmap with the specified color.
|
||||
* If the bitmap's config does not support alpha (e.g. 565) then the alpha
|
||||
* of the color is ignored (treated as opaque). If the config only supports
|
||||
* alpha (e.g. A1 or A8) then the color's r,g,b components are ignored.
|
||||
*/
|
||||
void eraseArea(const SkIRect& area, SkColor c) const;
|
||||
|
||||
/** Scroll (a subset of) the contents of this bitmap by dx/dy. If there are
|
||||
no pixels allocated (i.e. getPixels() returns null) the method will
|
||||
still update the inval region (if present). If the bitmap is immutable,
|
||||
@ -578,6 +475,14 @@ public:
|
||||
*/
|
||||
inline uint8_t* getAddr8(int x, int y) const;
|
||||
|
||||
/** Returns the address of the byte containing the pixel specified by x,y
|
||||
* for 1bit pixels.
|
||||
* In debug build, this asserts that the pixels are allocated and locked,
|
||||
* and that the config is 1-bit, however none of these checks are performed
|
||||
* in the release build.
|
||||
*/
|
||||
inline uint8_t* getAddr1(int x, int y) const;
|
||||
|
||||
/** Returns the color corresponding to the pixel specified by x,y for
|
||||
* colortable based bitmaps.
|
||||
* In debug build, this asserts that the pixels are allocated and locked,
|
||||
@ -627,8 +532,15 @@ public:
|
||||
*/
|
||||
bool canCopyTo(Config newConfig) const;
|
||||
|
||||
SK_ATTR_DEPRECATED("use setFilterLevel on SkPaint")
|
||||
bool hasMipMap() const;
|
||||
void buildMipMap(bool forceRebuild = false);
|
||||
void freeMipMap();
|
||||
|
||||
/** Given scale factors sx, sy, determine the miplevel available in the
|
||||
bitmap, and return it (this is the amount to shift matrix iterators
|
||||
by). If dst is not null, it is set to the correct level.
|
||||
*/
|
||||
int extractMipLevel(SkBitmap* dst, SkFixed sx, SkFixed sy);
|
||||
|
||||
#ifdef SK_BUILD_FOR_ANDROID
|
||||
bool hasHardwareMipMap() const {
|
||||
@ -676,8 +588,8 @@ public:
|
||||
buffers as they can optimize the recording process and avoid recording
|
||||
duplicate bitmaps and pixelRefs.
|
||||
*/
|
||||
void flatten(SkWriteBuffer&) const;
|
||||
void unflatten(SkReadBuffer&);
|
||||
void flatten(SkFlattenableWriteBuffer&) const;
|
||||
void unflatten(SkFlattenableReadBuffer&);
|
||||
|
||||
SkDEBUGCODE(void validate() const;)
|
||||
|
||||
@ -703,7 +615,7 @@ public:
|
||||
*/
|
||||
class HeapAllocator : public Allocator {
|
||||
public:
|
||||
virtual bool allocPixelRef(SkBitmap*, SkColorTable*) SK_OVERRIDE;
|
||||
virtual bool allocPixelRef(SkBitmap*, SkColorTable*);
|
||||
};
|
||||
|
||||
class RLEPixels {
|
||||
@ -734,13 +646,13 @@ private:
|
||||
mutable MipMap* fMipMap;
|
||||
|
||||
mutable SkPixelRef* fPixelRef;
|
||||
mutable size_t fPixelRefOffset;
|
||||
mutable int fPixelLockCount;
|
||||
// These are just caches from the locked pixelref
|
||||
// either user-specified (in which case it is not treated as mutable)
|
||||
// or a cache of the returned value from fPixelRef->lockPixels()
|
||||
mutable void* fPixels;
|
||||
mutable SkColorTable* fColorTable; // only meaningful for kIndex8
|
||||
|
||||
SkIPoint fPixelRefOrigin;
|
||||
|
||||
enum Flags {
|
||||
kImageIsOpaque_Flag = 0x01,
|
||||
kImageIsVolatile_Flag = 0x02,
|
||||
@ -754,20 +666,19 @@ private:
|
||||
#endif
|
||||
};
|
||||
|
||||
SkImageInfo fInfo;
|
||||
|
||||
uint32_t fRowBytes;
|
||||
|
||||
uint32_t fWidth;
|
||||
uint32_t fHeight;
|
||||
uint8_t fConfig;
|
||||
uint8_t fFlags;
|
||||
|
||||
void internalErase(const SkIRect&, U8CPU a, U8CPU r, U8CPU g, U8CPU b)const;
|
||||
uint8_t fBytesPerPixel; // based on config
|
||||
|
||||
/* Internal computations for safe size.
|
||||
*/
|
||||
static int64_t ComputeSafeSize64(Config config,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
size_t rowBytes);
|
||||
static Sk64 ComputeSafeSize64(Config config,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
size_t rowBytes);
|
||||
static size_t ComputeSafeSize(Config config,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
@ -779,16 +690,6 @@ private:
|
||||
void updatePixelsFromRef() const;
|
||||
|
||||
static SkFixed ComputeMipLevel(SkFixed sx, SkFixed dy);
|
||||
|
||||
/** Given scale factors sx, sy, determine the miplevel available in the
|
||||
bitmap, and return it (this is the amount to shift matrix iterators
|
||||
by). If dst is not null, it is set to the correct level.
|
||||
*/
|
||||
int extractMipLevel(SkBitmap* dst, SkFixed sx, SkFixed sy);
|
||||
bool hasMipMap() const;
|
||||
void freeMipMap();
|
||||
|
||||
friend struct SkBitmapProcState;
|
||||
};
|
||||
|
||||
class SkAutoLockPixels : public SkNoncopyable {
|
||||
@ -809,8 +710,6 @@ private:
|
||||
const SkBitmap& fBitmap;
|
||||
bool fDidLock;
|
||||
};
|
||||
//TODO(mtklein): uncomment when 71713004 lands and Chromium's fixed.
|
||||
//#define SkAutoLockPixels(...) SK_REQUIRE_LOCAL_VAR(SkAutoLockPixels)
|
||||
|
||||
/** Helper class that performs the lock/unlockColors calls on a colortable.
|
||||
The destructor will call unlockColors(false) if it has a bitmap's colortable
|
||||
@ -835,7 +734,7 @@ public:
|
||||
}
|
||||
~SkAutoLockColors() {
|
||||
if (fCTable) {
|
||||
fCTable->unlockColors();
|
||||
fCTable->unlockColors(false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -849,7 +748,7 @@ public:
|
||||
*/
|
||||
const SkPMColor* lockColors(SkColorTable* ctable) {
|
||||
if (fCTable) {
|
||||
fCTable->unlockColors();
|
||||
fCTable->unlockColors(false);
|
||||
}
|
||||
fCTable = ctable;
|
||||
fColors = ctable ? ctable->lockColors() : NULL;
|
||||
@ -864,37 +763,44 @@ private:
|
||||
SkColorTable* fCTable;
|
||||
const SkPMColor* fColors;
|
||||
};
|
||||
#define SkAutoLockColors(...) SK_REQUIRE_LOCAL_VAR(SkAutoLockColors)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline uint32_t* SkBitmap::getAddr32(int x, int y) const {
|
||||
SkASSERT(fPixels);
|
||||
SkASSERT(this->config() == kARGB_8888_Config);
|
||||
SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height());
|
||||
SkASSERT(fConfig == kARGB_8888_Config);
|
||||
SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
|
||||
return (uint32_t*)((char*)fPixels + y * fRowBytes + (x << 2));
|
||||
}
|
||||
|
||||
inline uint16_t* SkBitmap::getAddr16(int x, int y) const {
|
||||
SkASSERT(fPixels);
|
||||
SkASSERT(this->config() == kRGB_565_Config || this->config() == kARGB_4444_Config);
|
||||
SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height());
|
||||
SkASSERT(fConfig == kRGB_565_Config || fConfig == kARGB_4444_Config);
|
||||
SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
|
||||
return (uint16_t*)((char*)fPixels + y * fRowBytes + (x << 1));
|
||||
}
|
||||
|
||||
inline uint8_t* SkBitmap::getAddr8(int x, int y) const {
|
||||
SkASSERT(fPixels);
|
||||
SkASSERT(this->config() == kA8_Config || this->config() == kIndex8_Config);
|
||||
SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height());
|
||||
SkASSERT(fConfig == kA8_Config || fConfig == kIndex8_Config);
|
||||
SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
|
||||
return (uint8_t*)fPixels + y * fRowBytes + x;
|
||||
}
|
||||
|
||||
inline SkPMColor SkBitmap::getIndex8Color(int x, int y) const {
|
||||
SkASSERT(fPixels);
|
||||
SkASSERT(this->config() == kIndex8_Config);
|
||||
SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height());
|
||||
SkASSERT(fConfig == kIndex8_Config);
|
||||
SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
|
||||
SkASSERT(fColorTable);
|
||||
return (*fColorTable)[*((const uint8_t*)fPixels + y * fRowBytes + x)];
|
||||
}
|
||||
|
||||
// returns the address of the byte that contains the x coordinate
|
||||
inline uint8_t* SkBitmap::getAddr1(int x, int y) const {
|
||||
SkASSERT(fPixels);
|
||||
SkASSERT(fConfig == kA1_Config);
|
||||
SkASSERT((unsigned)x < fWidth && (unsigned)y < fHeight);
|
||||
return (uint8_t*)fPixels + y * fRowBytes + (x >> 3);
|
||||
}
|
||||
|
||||
#endif
|
@ -92,6 +92,7 @@ public:
|
||||
|
||||
static Proc32 PlatformProcs32(unsigned flags);
|
||||
static Proc PlatformProcs565(unsigned flags);
|
||||
static Proc PlatformProcs4444(unsigned flags);
|
||||
static ColorProc PlatformColorProc();
|
||||
|
||||
private:
|
@ -1,3 +1,4 @@
|
||||
|
||||
/*
|
||||
* Copyright 2006 The Android Open Source Project
|
||||
*
|
||||
@ -5,6 +6,7 @@
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SkCanvas_DEFINED
|
||||
#define SkCanvas_DEFINED
|
||||
|
||||
@ -16,18 +18,17 @@
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkPath.h"
|
||||
#include "SkRegion.h"
|
||||
#include "SkScalarCompare.h"
|
||||
#include "SkXfermode.h"
|
||||
|
||||
class SkBounder;
|
||||
class SkBaseDevice;
|
||||
class SkDevice;
|
||||
class SkDraw;
|
||||
class SkDrawFilter;
|
||||
class SkMetaData;
|
||||
class SkPicture;
|
||||
class SkRRect;
|
||||
class SkSurface;
|
||||
class SkSurface_Base;
|
||||
class GrContext;
|
||||
|
||||
/** \class SkCanvas
|
||||
|
||||
@ -48,26 +49,15 @@ class SK_API SkCanvas : public SkRefCnt {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkCanvas)
|
||||
|
||||
/**
|
||||
* Creates an empty canvas with no backing device/pixels, and zero
|
||||
* dimensions.
|
||||
*/
|
||||
SkCanvas();
|
||||
|
||||
/**
|
||||
* Creates a canvas of the specified dimensions, but explicitly not backed
|
||||
* by any device/pixels. Typically this use used by subclasses who handle
|
||||
* the draw calls in some other way.
|
||||
*/
|
||||
SkCanvas(int width, int height);
|
||||
|
||||
/** Construct a canvas with the specified device to draw into.
|
||||
|
||||
@param device Specifies a device for the canvas to draw into.
|
||||
*/
|
||||
explicit SkCanvas(SkBaseDevice* device);
|
||||
explicit SkCanvas(SkDevice* device);
|
||||
|
||||
/** Construct a canvas with the specified bitmap to draw into.
|
||||
/** Deprecated - Construct a canvas with the specified bitmap to draw into.
|
||||
@param bitmap Specifies a bitmap for the canvas to draw into. Its
|
||||
structure are copied to the canvas.
|
||||
*/
|
||||
@ -94,7 +84,7 @@ public:
|
||||
the bitmap of the pixels that the canvas draws into. The reference count
|
||||
of the returned device is not changed by this call.
|
||||
*/
|
||||
SkBaseDevice* getDevice() const;
|
||||
SkDevice* getDevice() const;
|
||||
|
||||
/**
|
||||
* saveLayer() can create another device (which is later drawn onto
|
||||
@ -109,19 +99,15 @@ public:
|
||||
* is drawn to, but is optional here, as there is a small perf hit
|
||||
* sometimes.
|
||||
*/
|
||||
SkBaseDevice* getTopDevice(bool updateMatrixClip = false) const;
|
||||
SkDevice* getTopDevice(bool updateMatrixClip = false) const;
|
||||
|
||||
/**
|
||||
* Create a new surface matching the specified info, one that attempts to
|
||||
* be maximally compatible when used with this canvas.
|
||||
* Shortcut for getDevice()->createCompatibleDevice(...).
|
||||
* If getDevice() == NULL, this method does nothing, and returns NULL.
|
||||
*/
|
||||
SkSurface* newSurface(const SkImageInfo&);
|
||||
|
||||
/**
|
||||
* Return the GPU context of the device that is associated with the canvas.
|
||||
* For a canvas with non-GPU device, NULL is returned.
|
||||
*/
|
||||
GrContext* getGrContext();
|
||||
SkDevice* createCompatibleDevice(SkBitmap::Config config,
|
||||
int width, int height,
|
||||
bool isOpaque);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -253,12 +239,6 @@ public:
|
||||
operate on this copy.
|
||||
When the balancing call to restore() is made, the previous matrix, clip,
|
||||
and drawFilter are restored.
|
||||
@param flags The flags govern what portion of the Matrix/Clip/drawFilter
|
||||
state the save (and matching restore) effect. For example,
|
||||
if only kMatrix is specified, then only the matrix state
|
||||
will be pushed and popped. Likewise for the clip if kClip
|
||||
is specified. However, the drawFilter is always affected
|
||||
by calls to save/restore.
|
||||
@return The value to pass to restoreToCount() to balance this save()
|
||||
*/
|
||||
virtual int save(SaveFlags flags = kMatrixClip_SaveFlag);
|
||||
@ -401,13 +381,6 @@ public:
|
||||
fAllowSoftClip = allow;
|
||||
}
|
||||
|
||||
/** EXPERIMENTAL -- only used for testing
|
||||
Set to simplify clip stack using path ops.
|
||||
*/
|
||||
void setAllowSimplifyClip(bool allow) {
|
||||
fAllowSimplifyClip = allow;
|
||||
}
|
||||
|
||||
/** Modify the current clip with the specified region. Note that unlike
|
||||
clipRect() and clipPath() which transform their arguments by the current
|
||||
matrix, clipRegion() assumes its argument is already in device
|
||||
@ -462,13 +435,14 @@ public:
|
||||
not intersect the current clip)
|
||||
*/
|
||||
bool quickRejectY(SkScalar top, SkScalar bottom) const {
|
||||
SkASSERT(top <= bottom);
|
||||
const SkRect& clipR = this->getLocalClipBounds();
|
||||
SkASSERT(SkScalarToCompareType(top) <= SkScalarToCompareType(bottom));
|
||||
const SkRectCompareType& clipR = this->getLocalClipBoundsCompareType();
|
||||
// In the case where the clip is empty and we are provided with a
|
||||
// negative top and positive bottom parameter then this test will return
|
||||
// false even though it will be clipped. We have chosen to exclude that
|
||||
// check as it is rare and would result double the comparisons.
|
||||
return top >= clipR.fBottom || bottom <= clipR.fTop;
|
||||
return SkScalarToCompareType(top) >= clipR.fBottom
|
||||
|| SkScalarToCompareType(bottom) <= clipR.fTop;
|
||||
}
|
||||
|
||||
/** Return the bounds of the current clip (in local coordinates) in the
|
||||
@ -678,11 +652,6 @@ public:
|
||||
bitmap's original width/height, then the bitmap will be drawn as if it
|
||||
were in a Shader with CLAMP mode. Thus the color outside of the original
|
||||
width/height will be the edge color replicated.
|
||||
|
||||
If a shader is present on the paint it will be ignored, except in the
|
||||
case where the bitmap is kA8_Config. In that case, the color is
|
||||
generated by the shader.
|
||||
|
||||
@param bitmap The bitmap to be drawn
|
||||
@param left The position of the left side of the bitmap being drawn
|
||||
@param top The position of the top side of the bitmap being drawn
|
||||
@ -691,16 +660,6 @@ public:
|
||||
virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
|
||||
const SkPaint* paint = NULL);
|
||||
|
||||
enum DrawBitmapRectFlags {
|
||||
kNone_DrawBitmapRectFlag = 0x0,
|
||||
/**
|
||||
* When filtering is enabled, allow the color samples outside of
|
||||
* the src rect (but still in the src bitmap) to bleed into the
|
||||
* drawn portion
|
||||
*/
|
||||
kBleed_DrawBitmapRectFlag = 0x1,
|
||||
};
|
||||
|
||||
/** Draw the specified bitmap, with the specified matrix applied (before the
|
||||
canvas' matrix is applied).
|
||||
@param bitmap The bitmap to be drawn
|
||||
@ -711,24 +670,22 @@ public:
|
||||
*/
|
||||
virtual void drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src,
|
||||
const SkRect& dst,
|
||||
const SkPaint* paint = NULL,
|
||||
DrawBitmapRectFlags flags = kNone_DrawBitmapRectFlag);
|
||||
const SkPaint* paint);
|
||||
|
||||
void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst,
|
||||
const SkPaint* paint = NULL) {
|
||||
this->drawBitmapRectToRect(bitmap, NULL, dst, paint, kNone_DrawBitmapRectFlag);
|
||||
const SkPaint* paint) {
|
||||
this->drawBitmapRectToRect(bitmap, NULL, dst, paint);
|
||||
}
|
||||
|
||||
void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* isrc,
|
||||
const SkRect& dst, const SkPaint* paint = NULL,
|
||||
DrawBitmapRectFlags flags = kNone_DrawBitmapRectFlag) {
|
||||
const SkRect& dst, const SkPaint* paint = NULL) {
|
||||
SkRect realSrcStorage;
|
||||
SkRect* realSrcPtr = NULL;
|
||||
if (isrc) {
|
||||
realSrcStorage.set(*isrc);
|
||||
realSrcPtr = &realSrcStorage;
|
||||
}
|
||||
this->drawBitmapRectToRect(bitmap, realSrcPtr, dst, paint, flags);
|
||||
this->drawBitmapRectToRect(bitmap, realSrcPtr, dst, paint);
|
||||
}
|
||||
|
||||
virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
|
||||
@ -741,9 +698,9 @@ public:
|
||||
* bitmap is the "center", then the center-rect should be [2, 2, 3, 3].
|
||||
*
|
||||
* If the dst is >= the bitmap size, then...
|
||||
* - The 4 corners are not stretched at all.
|
||||
* - The sides are stretched in only one axis.
|
||||
* - The center is stretched in both axes.
|
||||
* - The 4 corners are not stretch at all.
|
||||
* - The sides are stretch in only one axis.
|
||||
* - The center is stretch in both axes.
|
||||
* Else, for each axis where dst < bitmap,
|
||||
* - The corners shrink proportionally
|
||||
* - The sides (along the shrink axis) and center are not drawn
|
||||
@ -829,6 +786,21 @@ public:
|
||||
const SkPath& path, const SkMatrix* matrix,
|
||||
const SkPaint& paint);
|
||||
|
||||
#ifdef SK_BUILD_FOR_ANDROID
|
||||
/** Draw the text on path, with each character/glyph origin specified by the pos[]
|
||||
array. The origin is interpreted by the Align setting in the paint.
|
||||
@param text The text to be drawn
|
||||
@param byteLength The number of bytes to read from the text parameter
|
||||
@param pos Array of positions, used to position each character
|
||||
@param paint The paint used for the text (e.g. color, size, style)
|
||||
@param path The path to draw on
|
||||
@param matrix The canvas matrix
|
||||
*/
|
||||
void drawPosTextOnPath(const void* text, size_t byteLength,
|
||||
const SkPoint pos[], const SkPaint& paint,
|
||||
const SkPath& path, const SkMatrix* matrix);
|
||||
#endif
|
||||
|
||||
/** Draw the picture into this canvas. This method effective brackets the
|
||||
playback of the picture's draw calls with save/restore, so the state
|
||||
of this canvas will be unchanged after this call.
|
||||
@ -849,7 +821,7 @@ public:
|
||||
corresponding texs and colors arrays if non-null)
|
||||
@param vertices Array of vertices for the mesh
|
||||
@param texs May be null. If not null, specifies the coordinate
|
||||
in _texture_ space (not uv space) for each vertex.
|
||||
in texture space for each vertex.
|
||||
@param colors May be null. If not null, specifies a color for each
|
||||
vertex, to be interpolated across the triangle.
|
||||
@param xmode Used if both texs and colors are present. In this
|
||||
@ -873,24 +845,7 @@ public:
|
||||
subclasses like SkPicture's recording canvas, that can store the data
|
||||
and then play it back later (via another call to drawData).
|
||||
*/
|
||||
virtual void drawData(const void* data, size_t length) {
|
||||
// do nothing. Subclasses may do something with the data
|
||||
}
|
||||
|
||||
/** Add comments. beginCommentGroup/endCommentGroup open/close a new group.
|
||||
Each comment added via addComment is notionally attached to its
|
||||
enclosing group. Top-level comments simply belong to no group.
|
||||
*/
|
||||
virtual void beginCommentGroup(const char* description) {
|
||||
// do nothing. Subclasses may do something
|
||||
}
|
||||
virtual void addComment(const char* kywd, const char* value) {
|
||||
// do nothing. Subclasses may do something
|
||||
}
|
||||
virtual void endCommentGroup() {
|
||||
// do nothing. Subclasses may do something
|
||||
}
|
||||
|
||||
virtual void drawData(const void* data, size_t length);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -945,10 +900,11 @@ public:
|
||||
*/
|
||||
ClipType getClipType() const;
|
||||
|
||||
/** DEPRECATED -- need to move this guy to private/friend
|
||||
* Return the current device clip (concatenation of all clip calls).
|
||||
/** Return the current device clip (concatenation of all clip calls).
|
||||
* This does not account for the translate in any of the devices.
|
||||
* @return the current device clip (concatenation of all clip calls).
|
||||
*
|
||||
* DEPRECATED -- call getClipDeviceBounds() instead.
|
||||
*/
|
||||
const SkRegion& getTotalClip() const;
|
||||
|
||||
@ -996,7 +952,7 @@ public:
|
||||
|
||||
// These reflect the current device in the iterator
|
||||
|
||||
SkBaseDevice* device() const;
|
||||
SkDevice* device() const;
|
||||
const SkMatrix& matrix() const;
|
||||
const SkRegion& clip() const;
|
||||
const SkPaint& paint() const;
|
||||
@ -1016,34 +972,27 @@ public:
|
||||
};
|
||||
|
||||
protected:
|
||||
// default impl defers to getDevice()->newSurface(info)
|
||||
virtual SkSurface* onNewSurface(const SkImageInfo&);
|
||||
|
||||
// Returns the canvas to be used by DrawIter. Default implementation
|
||||
// returns this. Subclasses that encapsulate an indirect canvas may
|
||||
// need to overload this method. The impl must keep track of this, as it
|
||||
// is not released or deleted by the caller.
|
||||
virtual SkCanvas* canvasForDrawIter();
|
||||
|
||||
// all of the drawBitmap variants call this guy
|
||||
void commonDrawBitmap(const SkBitmap&, const SkIRect*, const SkMatrix&,
|
||||
const SkPaint& paint);
|
||||
|
||||
// Clip rectangle bounds. Called internally by saveLayer.
|
||||
// returns false if the entire rectangle is entirely clipped out
|
||||
// If non-NULL, The imageFilter parameter will be used to expand the clip
|
||||
// and offscreen bounds for any margin required by the filter DAG.
|
||||
bool clipRectBounds(const SkRect* bounds, SaveFlags flags,
|
||||
SkIRect* intersection,
|
||||
const SkImageFilter* imageFilter = NULL);
|
||||
|
||||
// Called by child classes that override clipPath and clipRRect to only
|
||||
// track fast conservative clip bounds, rather than exact clips.
|
||||
bool updateClipConservativelyUsingBounds(const SkRect&, SkRegion::Op,
|
||||
bool inverseFilled);
|
||||
SkIRect* intersection);
|
||||
|
||||
// notify our surface (if we have one) that we are about to draw, so it
|
||||
// can perform copy-on-write or invalidate any cached images
|
||||
void predrawNotify();
|
||||
|
||||
/**
|
||||
DEPRECATED -- need to remove when subclass stop relying on it.
|
||||
/** DEPRECATED -- use constructor(device)
|
||||
|
||||
Marked as 'protected' to avoid new clients using this before we can
|
||||
completely remove it.
|
||||
|
||||
@ -1051,7 +1000,7 @@ protected:
|
||||
reference count is incremented. If the canvas was already holding a
|
||||
device, its reference count is decremented. The new device is returned.
|
||||
*/
|
||||
virtual SkBaseDevice* setDevice(SkBaseDevice* device);
|
||||
virtual SkDevice* setDevice(SkDevice* device);
|
||||
|
||||
private:
|
||||
class MCRec;
|
||||
@ -1074,7 +1023,6 @@ private:
|
||||
fSurfaceBase = sb;
|
||||
}
|
||||
friend class SkSurface_Base;
|
||||
friend class SkSurface_Gpu;
|
||||
|
||||
bool fDeviceCMDirty; // cleared by updateDeviceCMCache()
|
||||
void updateDeviceCMCache();
|
||||
@ -1082,23 +1030,23 @@ private:
|
||||
friend class SkDrawIter; // needs setupDrawForLayerDevice()
|
||||
friend class AutoDrawLooper;
|
||||
|
||||
SkBaseDevice* createLayerDevice(SkBitmap::Config, int width, int height,
|
||||
bool isOpaque);
|
||||
SkDevice* createLayerDevice(SkBitmap::Config, int width, int height,
|
||||
bool isOpaque);
|
||||
|
||||
SkBaseDevice* init(SkBaseDevice*);
|
||||
SkDevice* init(SkDevice*);
|
||||
|
||||
// internal methods are not virtual, so they can safely be called by other
|
||||
// canvas apis, without confusing subclasses (like SkPictureRecording)
|
||||
void internalDrawBitmap(const SkBitmap&, const SkMatrix& m, const SkPaint* paint);
|
||||
void internalDrawBitmap(const SkBitmap&, const SkIRect*, const SkMatrix& m,
|
||||
const SkPaint* paint);
|
||||
void internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src,
|
||||
const SkRect& dst, const SkPaint* paint,
|
||||
DrawBitmapRectFlags flags);
|
||||
const SkRect& dst, const SkPaint* paint);
|
||||
void internalDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
|
||||
const SkRect& dst, const SkPaint* paint);
|
||||
void internalDrawPaint(const SkPaint& paint);
|
||||
int internalSaveLayer(const SkRect* bounds, const SkPaint* paint,
|
||||
SaveFlags, bool justForImageFilter);
|
||||
void internalDrawDevice(SkBaseDevice*, int x, int y, const SkPaint*);
|
||||
void internalDrawDevice(SkDevice*, int x, int y, const SkPaint*);
|
||||
|
||||
// shared by save() and saveLayer()
|
||||
int internalSave(SaveFlags flags);
|
||||
@ -1112,20 +1060,18 @@ private:
|
||||
/* These maintain a cache of the clip bounds in local coordinates,
|
||||
(converted to 2s-compliment if floats are slow).
|
||||
*/
|
||||
mutable SkRect fCachedLocalClipBounds;
|
||||
mutable bool fCachedLocalClipBoundsDirty;
|
||||
mutable SkRectCompareType fLocalBoundsCompareType;
|
||||
mutable bool fLocalBoundsCompareTypeDirty;
|
||||
bool fAllowSoftClip;
|
||||
bool fAllowSimplifyClip;
|
||||
|
||||
const SkRect& getLocalClipBounds() const {
|
||||
if (fCachedLocalClipBoundsDirty) {
|
||||
if (!this->getClipBounds(&fCachedLocalClipBounds)) {
|
||||
fCachedLocalClipBounds.setEmpty();
|
||||
}
|
||||
fCachedLocalClipBoundsDirty = false;
|
||||
const SkRectCompareType& getLocalClipBoundsCompareType() const {
|
||||
if (fLocalBoundsCompareTypeDirty) {
|
||||
this->computeLocalClipBoundsCompareType();
|
||||
fLocalBoundsCompareTypeDirty = false;
|
||||
}
|
||||
return fCachedLocalClipBounds;
|
||||
return fLocalBoundsCompareType;
|
||||
}
|
||||
void computeLocalClipBoundsCompareType() const;
|
||||
|
||||
class AutoValidateClip : ::SkNoncopyable {
|
||||
public:
|
||||
@ -1153,12 +1099,11 @@ private:
|
||||
*/
|
||||
class SkAutoCanvasRestore : SkNoncopyable {
|
||||
public:
|
||||
SkAutoCanvasRestore(SkCanvas* canvas, bool doSave) : fCanvas(canvas), fSaveCount(0) {
|
||||
if (fCanvas) {
|
||||
fSaveCount = canvas->getSaveCount();
|
||||
if (doSave) {
|
||||
canvas->save();
|
||||
}
|
||||
SkAutoCanvasRestore(SkCanvas* canvas, bool doSave) : fCanvas(canvas) {
|
||||
SkASSERT(canvas);
|
||||
fSaveCount = canvas->getSaveCount();
|
||||
if (doSave) {
|
||||
canvas->save();
|
||||
}
|
||||
}
|
||||
~SkAutoCanvasRestore() {
|
||||
@ -1182,28 +1127,5 @@ private:
|
||||
SkCanvas* fCanvas;
|
||||
int fSaveCount;
|
||||
};
|
||||
#define SkAutoCanvasRestore(...) SK_REQUIRE_LOCAL_VAR(SkAutoCanvasRestore)
|
||||
|
||||
/** Stack helper class to automatically open and close a comment block
|
||||
*/
|
||||
class SkAutoCommentBlock : SkNoncopyable {
|
||||
public:
|
||||
SkAutoCommentBlock(SkCanvas* canvas, const char* description) {
|
||||
fCanvas = canvas;
|
||||
if (NULL != fCanvas) {
|
||||
fCanvas->beginCommentGroup(description);
|
||||
}
|
||||
}
|
||||
|
||||
~SkAutoCommentBlock() {
|
||||
if (NULL != fCanvas) {
|
||||
fCanvas->endCommentGroup();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
SkCanvas* fCanvas;
|
||||
};
|
||||
#define SkAutoCommentBlock(...) SK_REQUIRE_LOCAL_VAR(SkAutoCommentBlock)
|
||||
|
||||
#endif
|
@ -10,15 +10,6 @@
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
/**
|
||||
* Computes a 32bit checksum from a blob of 32bit aligned data. This is meant
|
||||
* to be very very fast, as it is used internally by the font cache, in
|
||||
* conjuction with the entire raw key. This algorithm does not generate
|
||||
* unique values as well as others (e.g. MD5) but it performs much faster.
|
||||
* Skia's use cases can survive non-unique values (since the entire key is
|
||||
* always available). Clients should only be used in circumstances where speed
|
||||
* over uniqueness is at a premium.
|
||||
*/
|
||||
class SkChecksum : SkNoncopyable {
|
||||
private:
|
||||
/*
|
||||
@ -36,42 +27,6 @@ private:
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Calculate 32-bit Murmur hash (murmur3).
|
||||
* This should take 2-3x longer than SkChecksum::Compute, but is a considerably better hash.
|
||||
* See en.wikipedia.org/wiki/MurmurHash.
|
||||
*
|
||||
* @param data Memory address of the data block to be processed. Must be 32-bit aligned.
|
||||
* @param size Size of the data block in bytes. Must be a multiple of 4.
|
||||
* @param seed Initial hash seed. (optional)
|
||||
* @return hash result
|
||||
*/
|
||||
static uint32_t Murmur3(const uint32_t* data, size_t bytes, uint32_t seed=0) {
|
||||
SkASSERT(SkIsAlign4(bytes));
|
||||
const size_t words = bytes/4;
|
||||
|
||||
uint32_t hash = seed;
|
||||
for (size_t i = 0; i < words; i++) {
|
||||
uint32_t k = data[i];
|
||||
k *= 0xcc9e2d51;
|
||||
k = (k << 15) | (k >> 17);
|
||||
k *= 0x1b873593;
|
||||
|
||||
hash ^= k;
|
||||
hash = (hash << 13) | (hash >> 19);
|
||||
hash *= 5;
|
||||
hash += 0xe6546b64;
|
||||
}
|
||||
hash ^= bytes;
|
||||
hash ^= hash >> 16;
|
||||
hash *= 0x85ebca6b;
|
||||
hash ^= hash >> 13;
|
||||
hash *= 0xc2b2ae35;
|
||||
hash ^= hash >> 16;
|
||||
return hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute a 32-bit checksum for a given data block
|
||||
*
|
@ -42,7 +42,6 @@ public:
|
||||
size_t unalloc(void* ptr);
|
||||
|
||||
size_t totalCapacity() const { return fTotalCapacity; }
|
||||
size_t totalUsed() const { return fTotalUsed; }
|
||||
int blockCount() const { return fBlockCount; }
|
||||
|
||||
/**
|
||||
@ -59,7 +58,6 @@ private:
|
||||
size_t fMinSize;
|
||||
size_t fChunkSize;
|
||||
size_t fTotalCapacity;
|
||||
size_t fTotalUsed; // will be <= fTotalCapacity
|
||||
int fBlockCount;
|
||||
|
||||
Block* newBlock(size_t bytes, AllocFailType ftype);
|
@ -109,7 +109,7 @@ public:
|
||||
stack not to the element itself. That is the same clip path in different stacks will
|
||||
have a different ID since the elements produce different clip result in the context of
|
||||
their stacks. */
|
||||
int32_t getGenID() const { SkASSERT(kInvalidGenID != fGenID); return fGenID; }
|
||||
int32_t getGenID() const { return fGenID; }
|
||||
|
||||
/**
|
||||
* Gets the bounds of the clip element, either the rect or path bounds. (Whether the shape
|
||||
@ -315,13 +315,26 @@ public:
|
||||
*/
|
||||
bool isWideOpen() const;
|
||||
|
||||
/**
|
||||
* Add a callback function that will be called whenever a clip state
|
||||
* is no longer viable. This will occur whenever restore
|
||||
* is called or when a clipDevRect or clipDevPath call updates the
|
||||
* clip within an existing save/restore state. Each clip state is
|
||||
* represented by a unique generation ID.
|
||||
*/
|
||||
typedef void (*PFPurgeClipCB)(int genID, void* data);
|
||||
void addPurgeClipCallback(PFPurgeClipCB callback, void* data) const;
|
||||
|
||||
/**
|
||||
* Remove a callback added earlier via addPurgeClipCallback
|
||||
*/
|
||||
void removePurgeClipCallback(PFPurgeClipCB callback, void* data) const;
|
||||
|
||||
/**
|
||||
* The generation ID has three reserved values to indicate special
|
||||
* (potentially ignorable) cases
|
||||
*/
|
||||
static const int32_t kInvalidGenID = 0; //!< Invalid id that is never returned by
|
||||
//!< SkClipStack. Useful when caching clips
|
||||
//!< based on GenID.
|
||||
static const int32_t kInvalidGenID = 0;
|
||||
static const int32_t kEmptyGenID = 1; // no pixels writeable
|
||||
static const int32_t kWideOpenGenID = 2; // all pixels writeable
|
||||
|
||||
@ -427,10 +440,22 @@ private:
|
||||
// invalid ID.
|
||||
static int32_t gGenID;
|
||||
|
||||
struct ClipCallbackData {
|
||||
PFPurgeClipCB fCallback;
|
||||
void* fData;
|
||||
|
||||
friend bool operator==(const ClipCallbackData& a,
|
||||
const ClipCallbackData& b) {
|
||||
return a.fCallback == b.fCallback && a.fData == b.fData;
|
||||
}
|
||||
};
|
||||
|
||||
mutable SkTDArray<ClipCallbackData> fCallbackData;
|
||||
|
||||
/**
|
||||
* Restore the stack back to the specified save count.
|
||||
* Invoke all the purge callbacks passing in element's generation ID.
|
||||
*/
|
||||
void restoreTo(int saveCount);
|
||||
void purgeClip(Element* element);
|
||||
|
||||
/**
|
||||
* Return the next unique generation ID.
|
@ -73,9 +73,6 @@ static inline SkColor SkColorSetA(SkColor c, U8CPU a) {
|
||||
|
||||
// common colors
|
||||
|
||||
#define SK_AlphaTRANSPARENT 0x00 //!< transparent SkAlpha value
|
||||
#define SK_AlphaOPAQUE 0xFF //!< opaque SkAlpha value
|
||||
|
||||
#define SK_ColorTRANSPARENT 0x00000000 //!< transparent SkColor value
|
||||
|
||||
#define SK_ColorBLACK 0xFF000000 //!< black SkColor value
|
@ -18,14 +18,6 @@ class SkBitmap;
|
||||
class GrEffectRef;
|
||||
class GrContext;
|
||||
|
||||
/**
|
||||
* 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:
|
||||
SK_DECLARE_INST_COUNT(SkColorFilter)
|
||||
@ -128,14 +120,10 @@ public:
|
||||
*/
|
||||
virtual GrEffectRef* asNewEffect(GrContext*) const;
|
||||
|
||||
SkDEVCODE(virtual void toString(SkString* str) const = 0;)
|
||||
|
||||
SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
|
||||
SK_DEFINE_FLATTENABLE_TYPE(SkColorFilter)
|
||||
|
||||
protected:
|
||||
SkColorFilter() {}
|
||||
SkColorFilter(SkReadBuffer& rb) : INHERITED(rb) {}
|
||||
SkColorFilter(SkFlattenableReadBuffer& rb) : INHERITED(rb) {}
|
||||
|
||||
private:
|
||||
typedef SkFlattenable INHERITED;
|
@ -269,90 +269,36 @@ static inline SkPMColor SkFourByteInterp(SkPMColor src, SkPMColor dst,
|
||||
}
|
||||
|
||||
/**
|
||||
* 0xAARRGGBB -> 0x00AA00GG, 0x00RR00BB
|
||||
*/
|
||||
static inline void SkSplay(uint32_t color, uint32_t* ag, uint32_t* rb) {
|
||||
const uint32_t mask = 0x00FF00FF;
|
||||
*ag = (color >> 8) & mask;
|
||||
*rb = color & mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* 0xAARRGGBB -> 0x00AA00GG00RR00BB
|
||||
* (note, ARGB -> AGRB)
|
||||
*/
|
||||
static inline uint64_t SkSplay(uint32_t color) {
|
||||
const uint32_t mask = 0x00FF00FF;
|
||||
uint64_t agrb = (color >> 8) & mask; // 0x0000000000AA00GG
|
||||
agrb <<= 32; // 0x00AA00GG00000000
|
||||
agrb |= color & mask; // 0x00AA00GG00RR00BB
|
||||
return agrb;
|
||||
}
|
||||
|
||||
/**
|
||||
* 0xAAxxGGxx, 0xRRxxBBxx-> 0xAARRGGBB
|
||||
*/
|
||||
static inline uint32_t SkUnsplay(uint32_t ag, uint32_t rb) {
|
||||
const uint32_t mask = 0xFF00FF00;
|
||||
return (ag & mask) | ((rb & mask) >> 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* 0xAAxxGGxxRRxxBBxx -> 0xAARRGGBB
|
||||
* (note, AGRB -> ARGB)
|
||||
*/
|
||||
static inline uint32_t SkUnsplay(uint64_t agrb) {
|
||||
const uint32_t mask = 0xFF00FF00;
|
||||
return SkPMColor(
|
||||
((agrb & mask) >> 8) | // 0x00RR00BB
|
||||
((agrb >> 32) & mask)); // 0xAARRGGBB
|
||||
}
|
||||
|
||||
static inline SkPMColor SkFastFourByteInterp256_32(SkPMColor src, SkPMColor dst, unsigned scale) {
|
||||
SkASSERT(scale <= 256);
|
||||
|
||||
// Two 8-bit blends per two 32-bit registers, with space to make sure the math doesn't collide.
|
||||
uint32_t src_ag, src_rb, dst_ag, dst_rb;
|
||||
SkSplay(src, &src_ag, &src_rb);
|
||||
SkSplay(dst, &dst_ag, &dst_rb);
|
||||
|
||||
const uint32_t ret_ag = src_ag * scale + (256 - scale) * dst_ag;
|
||||
const uint32_t ret_rb = src_rb * scale + (256 - scale) * dst_rb;
|
||||
|
||||
return SkUnsplay(ret_ag, ret_rb);
|
||||
}
|
||||
|
||||
static inline SkPMColor SkFastFourByteInterp256_64(SkPMColor src, SkPMColor dst, unsigned scale) {
|
||||
SkASSERT(scale <= 256);
|
||||
// Four 8-bit blends in one 64-bit register, with space to make sure the math doesn't collide.
|
||||
return SkUnsplay(SkSplay(src) * scale + (256-scale) * SkSplay(dst));
|
||||
}
|
||||
|
||||
// TODO(mtklein): Replace slow versions with fast versions, using scale + (scale>>7) everywhere.
|
||||
|
||||
/**
|
||||
* Same as SkFourByteInterp256, but faster.
|
||||
*/
|
||||
static inline SkPMColor SkFastFourByteInterp256(SkPMColor src, SkPMColor dst, unsigned scale) {
|
||||
// On a 64-bit machine, _64 is about 10% faster than _32, but ~40% slower on a 32-bit machine.
|
||||
if (sizeof(void*) == 4) {
|
||||
return SkFastFourByteInterp256_32(src, dst, scale);
|
||||
} else {
|
||||
return SkFastFourByteInterp256_64(src, dst, scale);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Nearly the same as SkFourByteInterp, but faster and a touch more accurate, due to better
|
||||
* srcWeight scaling to [0, 256].
|
||||
* 32b optimized version; currently appears to be 10% faster even on 64b
|
||||
* architectures than an equivalent 64b version and 30% faster than
|
||||
* SkFourByteInterp(). Third parameter controls blending of the first two:
|
||||
* (src, dst, 0) returns dst
|
||||
* (src, dst, 0xFF) returns src
|
||||
* ** Does not match the results of SkFourByteInterp() because we use
|
||||
* a more accurate scale computation!
|
||||
* TODO: migrate Skia function to using an accurate 255->266 alpha
|
||||
* conversion.
|
||||
*/
|
||||
static inline SkPMColor SkFastFourByteInterp(SkPMColor src,
|
||||
SkPMColor dst,
|
||||
U8CPU srcWeight) {
|
||||
SkASSERT(srcWeight <= 255);
|
||||
SkASSERT(srcWeight < 256);
|
||||
|
||||
// Reorders ARGB to AG-RB in order to reduce the number of operations.
|
||||
const uint32_t mask = 0xFF00FF;
|
||||
uint32_t src_rb = src & mask;
|
||||
uint32_t src_ag = (src >> 8) & mask;
|
||||
uint32_t dst_rb = dst & mask;
|
||||
uint32_t dst_ag = (dst >> 8) & mask;
|
||||
|
||||
// scale = srcWeight + (srcWeight >> 7) is more accurate than
|
||||
// scale = srcWeight + 1, but 7% slower
|
||||
return SkFastFourByteInterp256(src, dst, srcWeight + (srcWeight >> 7));
|
||||
int scale = srcWeight + (srcWeight >> 7);
|
||||
|
||||
uint32_t ret_rb = src_rb * scale + (256 - scale) * dst_rb;
|
||||
uint32_t ret_ag = src_ag * scale + (256 - scale) * dst_ag;
|
||||
|
||||
return (ret_ag & ~mask) | ((ret_rb & ~mask) >> 8);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -367,9 +313,9 @@ static inline SkPMColor SkPackARGB32NoCheck(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
|
||||
static inline
|
||||
SkPMColor SkPremultiplyARGBInline(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
|
||||
SkA32Assert(a);
|
||||
SkR32Assert(r);
|
||||
SkG32Assert(g);
|
||||
SkB32Assert(b);
|
||||
SkA32Assert(r);
|
||||
SkA32Assert(g);
|
||||
SkA32Assert(b);
|
||||
|
||||
if (a != 255) {
|
||||
r = SkMulDiv255Round(r, a);
|
||||
@ -383,6 +329,7 @@ SK_API extern const uint32_t gMask_00FF00FF;
|
||||
|
||||
static inline uint32_t SkAlphaMulQ(uint32_t c, unsigned scale) {
|
||||
uint32_t mask = gMask_00FF00FF;
|
||||
// uint32_t mask = 0xFF00FF;
|
||||
|
||||
uint32_t rb = ((c & mask) * scale) >> 8;
|
||||
uint32_t ag = ((c >> 8) & mask) * scale;
|
||||
@ -886,29 +833,29 @@ static inline SkPMColor SkBlendLCD16Opaque(int srcR, int srcG, int srcB,
|
||||
SkBlend32(srcB, dstB, maskB));
|
||||
}
|
||||
|
||||
static inline void SkBlitLCD16Row(SkPMColor dst[], const uint16_t mask[],
|
||||
SkColor src, int width, SkPMColor) {
|
||||
int srcA = SkColorGetA(src);
|
||||
int srcR = SkColorGetR(src);
|
||||
int srcG = SkColorGetG(src);
|
||||
int srcB = SkColorGetB(src);
|
||||
static inline void SkBlitLCD16Row(SkPMColor dst[], const uint16_t src[],
|
||||
SkColor color, int width, SkPMColor) {
|
||||
int srcA = SkColorGetA(color);
|
||||
int srcR = SkColorGetR(color);
|
||||
int srcG = SkColorGetG(color);
|
||||
int srcB = SkColorGetB(color);
|
||||
|
||||
srcA = SkAlpha255To256(srcA);
|
||||
|
||||
for (int i = 0; i < width; i++) {
|
||||
dst[i] = SkBlendLCD16(srcA, srcR, srcG, srcB, dst[i], mask[i]);
|
||||
dst[i] = SkBlendLCD16(srcA, srcR, srcG, srcB, dst[i], src[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SkBlitLCD16OpaqueRow(SkPMColor dst[], const uint16_t mask[],
|
||||
SkColor src, int width,
|
||||
static inline void SkBlitLCD16OpaqueRow(SkPMColor dst[], const uint16_t src[],
|
||||
SkColor color, int width,
|
||||
SkPMColor opaqueDst) {
|
||||
int srcR = SkColorGetR(src);
|
||||
int srcG = SkColorGetG(src);
|
||||
int srcB = SkColorGetB(src);
|
||||
int srcR = SkColorGetR(color);
|
||||
int srcG = SkColorGetG(color);
|
||||
int srcB = SkColorGetB(color);
|
||||
|
||||
for (int i = 0; i < width; i++) {
|
||||
dst[i] = SkBlendLCD16Opaque(srcR, srcG, srcB, dst[i], mask[i],
|
||||
dst[i] = SkBlendLCD16Opaque(srcR, srcG, srcB, dst[i], src[i],
|
||||
opaqueDst);
|
||||
}
|
||||
}
|
@ -52,8 +52,8 @@ public:
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkColorShader)
|
||||
|
||||
protected:
|
||||
SkColorShader(SkReadBuffer&);
|
||||
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
|
||||
SkColorShader(SkFlattenableReadBuffer&);
|
||||
virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
|
112
gfx/skia/include/core/SkColorTable.h
Normal file
112
gfx/skia/include/core/SkColorTable.h
Normal file
@ -0,0 +1,112 @@
|
||||
|
||||
/*
|
||||
* 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 SkColorTable_DEFINED
|
||||
#define SkColorTable_DEFINED
|
||||
|
||||
#include "SkColor.h"
|
||||
#include "SkFlattenable.h"
|
||||
|
||||
/** \class SkColorTable
|
||||
|
||||
SkColorTable holds an array SkPMColors (premultiplied 32-bit colors) used by
|
||||
8-bit bitmaps, where the bitmap bytes are interpreted as indices into the colortable.
|
||||
*/
|
||||
class SkColorTable : public SkFlattenable {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkColorTable)
|
||||
|
||||
/** Makes a deep copy of colors.
|
||||
*/
|
||||
SkColorTable(const SkColorTable& src);
|
||||
/** Preallocates the colortable to have 'count' colors, which
|
||||
* are initially set to 0.
|
||||
*/
|
||||
explicit SkColorTable(int count);
|
||||
SkColorTable(const SkPMColor colors[], int count);
|
||||
virtual ~SkColorTable();
|
||||
|
||||
enum Flags {
|
||||
kColorsAreOpaque_Flag = 0x01 //!< if set, all of the colors in the table are opaque (alpha==0xFF)
|
||||
};
|
||||
/** Returns the flag bits for the color table. These can be changed with setFlags().
|
||||
*/
|
||||
unsigned getFlags() const { return fFlags; }
|
||||
/** Set the flags for the color table. See the Flags enum for possible values.
|
||||
*/
|
||||
void setFlags(unsigned flags);
|
||||
|
||||
bool isOpaque() const { return (fFlags & kColorsAreOpaque_Flag) != 0; }
|
||||
void setIsOpaque(bool isOpaque);
|
||||
|
||||
/** Returns the number of colors in the table.
|
||||
*/
|
||||
int count() const { return fCount; }
|
||||
|
||||
/** Returns the specified color from the table. In the debug build, this asserts that
|
||||
the index is in range (0 <= index < count).
|
||||
*/
|
||||
SkPMColor operator[](int index) const {
|
||||
SkASSERT(fColors != NULL && (unsigned)index < fCount);
|
||||
return fColors[index];
|
||||
}
|
||||
|
||||
/** Specify the number of colors in the color table. This does not initialize the colors
|
||||
to any value, just allocates memory for them. To initialize the values, either call
|
||||
setColors(array, count), or follow setCount(count) with a call to
|
||||
lockColors()/{set the values}/unlockColors(true).
|
||||
*/
|
||||
// void setColors(int count) { this->setColors(NULL, count); }
|
||||
// void setColors(const SkPMColor[], int count);
|
||||
|
||||
/** Return the array of colors for reading and/or writing. This must be
|
||||
balanced by a call to unlockColors(changed?), telling the colortable if
|
||||
the colors were changed during the lock.
|
||||
*/
|
||||
SkPMColor* lockColors() {
|
||||
SkDEBUGCODE(sk_atomic_inc(&fColorLockCount);)
|
||||
return fColors;
|
||||
}
|
||||
/** Balancing call to lockColors(). If the colors have been changed, pass true.
|
||||
*/
|
||||
void unlockColors(bool changed);
|
||||
|
||||
/** Similar to lockColors(), lock16BitCache() returns the array of
|
||||
RGB16 colors that mirror the 32bit colors. However, this function
|
||||
will return null if kColorsAreOpaque_Flag is not set.
|
||||
Also, unlike lockColors(), the returned array here cannot be modified.
|
||||
*/
|
||||
const uint16_t* lock16BitCache();
|
||||
/** Balancing call to lock16BitCache().
|
||||
*/
|
||||
void unlock16BitCache() {
|
||||
SkASSERT(f16BitCacheLockCount > 0);
|
||||
SkDEBUGCODE(f16BitCacheLockCount -= 1);
|
||||
}
|
||||
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkColorTable)
|
||||
|
||||
protected:
|
||||
explicit SkColorTable(SkFlattenableReadBuffer&);
|
||||
void flatten(SkFlattenableWriteBuffer&) const;
|
||||
|
||||
private:
|
||||
SkPMColor* fColors;
|
||||
uint16_t* f16BitCache;
|
||||
uint16_t fCount;
|
||||
uint8_t fFlags;
|
||||
SkDEBUGCODE(int fColorLockCount;)
|
||||
SkDEBUGCODE(int f16BitCacheLockCount;)
|
||||
|
||||
void inval16BitCache();
|
||||
|
||||
typedef SkFlattenable INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
@ -43,8 +43,8 @@ public:
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposeShader)
|
||||
|
||||
protected:
|
||||
SkComposeShader(SkReadBuffer& );
|
||||
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
|
||||
SkComposeShader(SkFlattenableReadBuffer& );
|
||||
virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
|
@ -11,16 +11,14 @@
|
||||
#ifndef SkData_DEFINED
|
||||
#define SkData_DEFINED
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
struct SkFILE;
|
||||
#include "SkFlattenable.h"
|
||||
|
||||
/**
|
||||
* SkData holds an immutable data buffer. Not only is the data immutable,
|
||||
* but the actual ptr that is returned (by data() or bytes()) is guaranteed
|
||||
* to always be the same for the life of this instance.
|
||||
*/
|
||||
class SK_API SkData : public SkRefCnt {
|
||||
class SK_API SkData : public SkFlattenable {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkData)
|
||||
|
||||
@ -91,28 +89,10 @@ public:
|
||||
static SkData* NewFromMalloc(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.
|
||||
* Create a new dataref from a pointer allocated by mmap. The Data object
|
||||
* will handle calling munmap().
|
||||
*/
|
||||
static SkData* NewFromFileName(const char path[]);
|
||||
|
||||
/**
|
||||
* Create a new dataref from a SkFILE.
|
||||
* This does not take ownership of the SkFILE, nor close it.
|
||||
* The caller is free to close the SkFILE at its convenience.
|
||||
* The SkFILE must be open for reading only.
|
||||
* Returns NULL on failure.
|
||||
*/
|
||||
static SkData* NewFromFILE(SkFILE* 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 SkData* NewFromFD(int fd);
|
||||
static SkData* NewFromMMap(const void* data, size_t length);
|
||||
|
||||
/**
|
||||
* Create a new dataref using a subset of the data in the specified
|
||||
@ -126,6 +106,12 @@ public:
|
||||
*/
|
||||
static SkData* NewEmpty();
|
||||
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkData)
|
||||
|
||||
protected:
|
||||
SkData(SkFlattenableReadBuffer&);
|
||||
virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
ReleaseProc fReleaseProc;
|
||||
void* fReleaseProcContext;
|
||||
@ -136,13 +122,41 @@ private:
|
||||
SkData(const void* ptr, size_t size, ReleaseProc, void* context);
|
||||
virtual ~SkData();
|
||||
|
||||
// Called the first time someone calls NewEmpty to initialize the singleton.
|
||||
static void NewEmptyImpl(int/*unused*/);
|
||||
// This is here because SkAutoTUnref creates an internal helper class
|
||||
// that derives from SkData (i.e., BlockRef) to prevent refs\unrefs.
|
||||
// This helper class generates a compiler warning on Windows since the
|
||||
// SkData's destructor is private. This friending gives the helper class
|
||||
// access to the destructor.
|
||||
friend class SkAutoTUnref<SkData>::BlockRef<SkData>;
|
||||
|
||||
typedef SkRefCnt INHERITED;
|
||||
typedef SkFlattenable INHERITED;
|
||||
};
|
||||
|
||||
/** Typedef of SkAutoTUnref<SkData> for automatically unref-ing a SkData. */
|
||||
typedef SkAutoTUnref<SkData> SkAutoDataUnref;
|
||||
/**
|
||||
* Specialized version of SkAutoTUnref<SkData> for automatically unref-ing a
|
||||
* SkData.
|
||||
*/
|
||||
class SkAutoDataUnref : SkNoncopyable {
|
||||
public:
|
||||
SkAutoDataUnref(SkData* data) : fRef(data) {}
|
||||
~SkAutoDataUnref() {
|
||||
SkSafeUnref(fRef);
|
||||
}
|
||||
|
||||
SkData* get() const { return fRef; }
|
||||
|
||||
void release() {
|
||||
if (fRef) {
|
||||
fRef->unref();
|
||||
fRef = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
SkData *operator->() const { return fRef; }
|
||||
operator SkData*() { return fRef; }
|
||||
|
||||
private:
|
||||
SkData* fRef;
|
||||
};
|
||||
|
||||
#endif
|
88
gfx/skia/include/core/SkDataSet.h
Normal file
88
gfx/skia/include/core/SkDataSet.h
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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 SkDataSet_DEFINED
|
||||
#define SkDataSet_DEFINED
|
||||
|
||||
#include "SkData.h"
|
||||
#include "SkFlattenable.h"
|
||||
|
||||
class SkStream;
|
||||
class SkWStream;
|
||||
|
||||
class SkDataSet : public SkFlattenable {
|
||||
public:
|
||||
/**
|
||||
* Returns a new empty dataset. Note: since SkDataSet is immutable, this
|
||||
* "new" set may be the same one that was returned before, but each
|
||||
* returned object must have its reference-count balanced regardless.
|
||||
*
|
||||
* SkDataSet* empty = SkDataSet::NewEmpty();
|
||||
* ...
|
||||
* empty->unref();
|
||||
*/
|
||||
static SkDataSet* NewEmpty();
|
||||
|
||||
struct Pair {
|
||||
const char* fKey;
|
||||
SkData* fValue;
|
||||
};
|
||||
|
||||
SkDataSet(const char key[], SkData* value);
|
||||
SkDataSet(const Pair[], int count);
|
||||
virtual ~SkDataSet();
|
||||
|
||||
bool isEmpty() const { return 0 == fCount; }
|
||||
int count() const { return fCount; }
|
||||
SkData* find(const char name[]) const;
|
||||
|
||||
class Iter {
|
||||
public:
|
||||
Iter(const SkDataSet& ds) {
|
||||
fPair = ds.fPairs;
|
||||
fStop = ds.fPairs + ds.fCount;
|
||||
}
|
||||
|
||||
const char* key() const {
|
||||
SkASSERT(!this->done());
|
||||
return fPair->fKey;
|
||||
}
|
||||
|
||||
SkData* value() const {
|
||||
SkASSERT(!this->done());
|
||||
return fPair->fValue;
|
||||
}
|
||||
|
||||
bool done() const { return fPair >= fStop; }
|
||||
void next() {
|
||||
SkASSERT(!this->done());
|
||||
fPair += 1;
|
||||
}
|
||||
|
||||
private:
|
||||
const SkDataSet::Pair* fPair;
|
||||
const SkDataSet::Pair* fStop;
|
||||
};
|
||||
|
||||
explicit SkDataSet(SkStream*);
|
||||
void writeToStream(SkWStream*) const;
|
||||
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDataSet)
|
||||
|
||||
protected:
|
||||
SkDataSet(SkFlattenableReadBuffer&);
|
||||
virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
int32_t fCount;
|
||||
uint32_t fKeySize;
|
||||
Pair* fPairs;
|
||||
|
||||
typedef SkFlattenable INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
@ -81,7 +81,7 @@ public:
|
||||
void reset(const SkDeque& d, IterStart startLoc);
|
||||
|
||||
private:
|
||||
SkDeque::Block* fCurBlock;
|
||||
SkDeque::Block* fCurBlock;
|
||||
char* fPos;
|
||||
size_t fElemSize;
|
||||
};
|
@ -23,23 +23,60 @@ class SkMatrix;
|
||||
class SkMetaData;
|
||||
class SkRegion;
|
||||
|
||||
class GrRenderTarget;
|
||||
// This is an opaque class, not interpreted by skia
|
||||
class SkGpuRenderTarget;
|
||||
|
||||
class SK_API SkBaseDevice : public SkRefCnt {
|
||||
class SK_API SkDevice : public SkRefCnt {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkBaseDevice)
|
||||
SK_DECLARE_INST_COUNT(SkDevice)
|
||||
|
||||
/**
|
||||
* Construct a new device.
|
||||
* Construct a new device with the specified bitmap as its backend. It is
|
||||
* valid for the bitmap to have no pixels associated with it. In that case,
|
||||
* any drawing to this device will have no effect.
|
||||
*/
|
||||
SkBaseDevice();
|
||||
SkDevice(const SkBitmap& bitmap);
|
||||
|
||||
/**
|
||||
* Construct a new device.
|
||||
* Construct a new device with the specified bitmap as its backend. It is
|
||||
* valid for the bitmap to have no pixels associated with it. In that case,
|
||||
* any drawing to this device will have no effect.
|
||||
*/
|
||||
SkBaseDevice(const SkDeviceProperties& deviceProperties);
|
||||
SkDevice(const SkBitmap& bitmap, const SkDeviceProperties& deviceProperties);
|
||||
|
||||
virtual ~SkBaseDevice();
|
||||
/**
|
||||
* Create a new raster device and have the pixels be automatically
|
||||
* allocated. The rowBytes of the device will be computed automatically
|
||||
* based on the config and the width.
|
||||
*
|
||||
* @param config The desired config for the pixels. If the request cannot
|
||||
* be met, the closest matching support config will be used.
|
||||
* @param width width (in pixels) of the device
|
||||
* @param height height (in pixels) of the device
|
||||
* @param isOpaque Set to true if it is known that all of the pixels will
|
||||
* be drawn to opaquely. Used as an accelerator when drawing
|
||||
* these pixels to another device.
|
||||
*/
|
||||
SkDevice(SkBitmap::Config config, int width, int height, bool isOpaque = false);
|
||||
|
||||
/**
|
||||
* Create a new raster device and have the pixels be automatically
|
||||
* allocated. The rowBytes of the device will be computed automatically
|
||||
* based on the config and the width.
|
||||
*
|
||||
* @param config The desired config for the pixels. If the request cannot
|
||||
* be met, the closest matching support config will be used.
|
||||
* @param width width (in pixels) of the device
|
||||
* @param height height (in pixels) of the device
|
||||
* @param isOpaque Set to true if it is known that all of the pixels will
|
||||
* be drawn to opaquely. Used as an accelerator when drawing
|
||||
* these pixels to another device.
|
||||
* @param deviceProperties Properties which affect compositing.
|
||||
*/
|
||||
SkDevice(SkBitmap::Config config, int width, int height, bool isOpaque,
|
||||
const SkDeviceProperties& deviceProperties);
|
||||
|
||||
virtual ~SkDevice();
|
||||
|
||||
/**
|
||||
* Creates a device that is of the same type as this device (e.g. SW-raster,
|
||||
@ -52,23 +89,25 @@ public:
|
||||
* draw into this device such that all of the pixels will
|
||||
* be opaque.
|
||||
*/
|
||||
SkBaseDevice* createCompatibleDevice(SkBitmap::Config config,
|
||||
int width, int height,
|
||||
bool isOpaque);
|
||||
SkDevice* createCompatibleDevice(SkBitmap::Config config,
|
||||
int width, int height,
|
||||
bool isOpaque);
|
||||
|
||||
SkMetaData& getMetaData();
|
||||
|
||||
enum Capabilities {
|
||||
kVector_Capability = 0x1, //!< mask indicating a vector representation
|
||||
kGL_Capability = 0x1, //!< mask indicating GL support
|
||||
kVector_Capability = 0x2, //!< mask indicating a vector representation
|
||||
kAll_Capabilities = 0x3
|
||||
};
|
||||
virtual uint32_t getDeviceCapabilities() = 0;
|
||||
virtual uint32_t getDeviceCapabilities() { return 0; }
|
||||
|
||||
/** Return the width of the device (in pixels).
|
||||
*/
|
||||
virtual int width() const = 0;
|
||||
virtual int width() const { return fBitmap.width(); }
|
||||
/** Return the height of the device (in pixels).
|
||||
*/
|
||||
virtual int height() const = 0;
|
||||
virtual int height() const { return fBitmap.height(); }
|
||||
|
||||
/** Return the image properties of the device. */
|
||||
virtual const SkDeviceProperties& getDeviceProperties() const {
|
||||
@ -81,22 +120,16 @@ public:
|
||||
* canvas. The root device will have its top-left at 0,0, but other devices
|
||||
* such as those associated with saveLayer may have a non-zero origin.
|
||||
*/
|
||||
void getGlobalBounds(SkIRect* bounds) const {
|
||||
SkASSERT(bounds);
|
||||
const SkIPoint& origin = this->getOrigin();
|
||||
bounds->setXYWH(origin.x(), origin.y(), this->width(), this->height());
|
||||
}
|
||||
void getGlobalBounds(SkIRect* bounds) const;
|
||||
|
||||
|
||||
/** Returns true if the device's bitmap's config treats every pixel as
|
||||
/** Returns true if the device's bitmap's config treats every pixels as
|
||||
implicitly opaque.
|
||||
*/
|
||||
virtual bool isOpaque() const = 0;
|
||||
bool isOpaque() const { return fBitmap.isOpaque(); }
|
||||
|
||||
/** Return the bitmap config of the device's pixels
|
||||
*/
|
||||
SK_ATTR_DEPRECATED("want to hide configness of the device -- don't use")
|
||||
virtual SkBitmap::Config config() const = 0;
|
||||
*/
|
||||
SkBitmap::Config config() const { return fBitmap.getConfig(); }
|
||||
|
||||
/** Return the bitmap associated with this device. Call this each time you need
|
||||
to access the bitmap, as it notifies the subclass to perform any flushing
|
||||
@ -122,12 +155,12 @@ public:
|
||||
* not kARGB_8888_Config then this parameter is ignored.
|
||||
*/
|
||||
virtual void writePixels(const SkBitmap& bitmap, int x, int y,
|
||||
SkCanvas::Config8888 config8888 = SkCanvas::kNative_Premul_Config8888) = 0;
|
||||
SkCanvas::Config8888 config8888 = SkCanvas::kNative_Premul_Config8888);
|
||||
|
||||
/**
|
||||
* Return the device's associated gpu render target, or NULL.
|
||||
*/
|
||||
virtual GrRenderTarget* accessRenderTarget() = 0;
|
||||
virtual SkGpuRenderTarget* accessRenderTarget() { return NULL; }
|
||||
|
||||
|
||||
/**
|
||||
@ -139,7 +172,7 @@ public:
|
||||
/**
|
||||
* onAttachToCanvas is invoked whenever a device is installed in a canvas
|
||||
* (i.e., setDevice, saveLayer (for the new device created by the save),
|
||||
* and SkCanvas' SkBaseDevice & SkBitmap -taking ctors). It allows the
|
||||
* and SkCanvas' SkDevice & SkBitmap -taking ctors). It allows the
|
||||
* devices to prepare for drawing (e.g., locking their pixels, etc.)
|
||||
*/
|
||||
virtual void onAttachToCanvas(SkCanvas*) {
|
||||
@ -181,9 +214,9 @@ protected:
|
||||
* textflags parameter (output) and return true. If the paint is fine as
|
||||
* is, then ignore the textflags parameter and return false.
|
||||
*
|
||||
* The baseclass SkBaseDevice filters based on its depth and blitters.
|
||||
* The baseclass SkDevice filters based on its depth and blitters.
|
||||
*/
|
||||
virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) = 0;
|
||||
virtual bool filterTextFlags(const SkPaint& paint, TextFlags*);
|
||||
|
||||
/**
|
||||
*
|
||||
@ -202,14 +235,16 @@ protected:
|
||||
* passed in).
|
||||
*/
|
||||
virtual void setMatrixClip(const SkMatrix&, const SkRegion&,
|
||||
const SkClipStack&) {};
|
||||
const SkClipStack&);
|
||||
|
||||
/** Clears the entire device to the specified color (including alpha).
|
||||
* Ignores the clip.
|
||||
*/
|
||||
virtual void clear(SkColor color) = 0;
|
||||
virtual void clear(SkColor color);
|
||||
|
||||
SK_ATTR_DEPRECATED("use clear() instead")
|
||||
/**
|
||||
* Deprecated name for clear.
|
||||
*/
|
||||
void eraseColor(SkColor eraseColor) { this->clear(eraseColor); }
|
||||
|
||||
/** These are called inside the per-device-layer loop for each draw call.
|
||||
@ -217,16 +252,13 @@ protected:
|
||||
and are handling any looping from the paint, and any effects from the
|
||||
DrawFilter.
|
||||
*/
|
||||
virtual void drawPaint(const SkDraw&, const SkPaint& paint) = 0;
|
||||
virtual void drawPaint(const SkDraw&, const SkPaint& paint);
|
||||
virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
|
||||
const SkPoint[], const SkPaint& paint) = 0;
|
||||
const SkPoint[], const SkPaint& paint);
|
||||
virtual void drawRect(const SkDraw&, const SkRect& r,
|
||||
const SkPaint& paint) = 0;
|
||||
const SkPaint& paint);
|
||||
virtual void drawOval(const SkDraw&, const SkRect& oval,
|
||||
const SkPaint& paint) = 0;
|
||||
virtual void drawRRect(const SkDraw&, const SkRRect& rr,
|
||||
const SkPaint& paint) = 0;
|
||||
|
||||
const SkPaint& paint);
|
||||
/**
|
||||
* If pathIsMutable, then the implementation is allowed to cast path to a
|
||||
* non-const pointer and modify it in place (as an optimization). Canvas
|
||||
@ -241,11 +273,12 @@ protected:
|
||||
virtual void drawPath(const SkDraw&, const SkPath& path,
|
||||
const SkPaint& paint,
|
||||
const SkMatrix* prePathMatrix = NULL,
|
||||
bool pathIsMutable = false) = 0;
|
||||
bool pathIsMutable = false);
|
||||
virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
|
||||
const SkMatrix& matrix, const SkPaint& paint) = 0;
|
||||
const SkIRect* srcRectOrNull,
|
||||
const SkMatrix& matrix, const SkPaint& paint);
|
||||
virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
|
||||
int x, int y, const SkPaint& paint) = 0;
|
||||
int x, int y, const SkPaint& paint);
|
||||
|
||||
/**
|
||||
* The default impl. will create a bitmap-shader from the bitmap,
|
||||
@ -253,31 +286,35 @@ protected:
|
||||
*/
|
||||
virtual void drawBitmapRect(const SkDraw&, const SkBitmap&,
|
||||
const SkRect* srcOrNull, const SkRect& dst,
|
||||
const SkPaint& paint,
|
||||
SkCanvas::DrawBitmapRectFlags flags) = 0;
|
||||
const SkPaint& paint);
|
||||
|
||||
/**
|
||||
* Does not handle text decoration.
|
||||
* Decorations (underline and stike-thru) will be handled by SkCanvas.
|
||||
*/
|
||||
virtual void drawText(const SkDraw&, const void* text, size_t len,
|
||||
SkScalar x, SkScalar y, const SkPaint& paint) = 0;
|
||||
SkScalar x, SkScalar y, const SkPaint& paint);
|
||||
virtual void drawPosText(const SkDraw&, const void* text, size_t len,
|
||||
const SkScalar pos[], SkScalar constY,
|
||||
int scalarsPerPos, const SkPaint& paint) = 0;
|
||||
int scalarsPerPos, const SkPaint& paint);
|
||||
virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
|
||||
const SkPath& path, const SkMatrix* matrix,
|
||||
const SkPaint& paint) = 0;
|
||||
const SkPaint& paint);
|
||||
#ifdef SK_BUILD_FOR_ANDROID
|
||||
virtual void drawPosTextOnPath(const SkDraw& draw, const void* text, size_t len,
|
||||
const SkPoint pos[], const SkPaint& paint,
|
||||
const SkPath& path, const SkMatrix* matrix);
|
||||
#endif
|
||||
virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
|
||||
const SkPoint verts[], const SkPoint texs[],
|
||||
const SkColor colors[], SkXfermode* xmode,
|
||||
const uint16_t indices[], int indexCount,
|
||||
const SkPaint& paint) = 0;
|
||||
const SkPaint& paint);
|
||||
/** The SkDevice passed will be an SkDevice which was returned by a call to
|
||||
onCreateCompatibleDevice on this device with kSaveLayer_Usage.
|
||||
*/
|
||||
virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
|
||||
const SkPaint&) = 0;
|
||||
virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
|
||||
const SkPaint&);
|
||||
|
||||
/**
|
||||
* On success (returns true), copy the device pixels into the bitmap.
|
||||
@ -313,10 +350,20 @@ protected:
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Update as needed the pixel value in the bitmap, so that the caller can
|
||||
access the pixels directly.
|
||||
@return The device contents as a bitmap
|
||||
access the pixels directly. Note: only the pixels field should be
|
||||
altered. The config/width/height/rowbytes must remain unchanged.
|
||||
@param bitmap The device's bitmap
|
||||
@return Echo the bitmap parameter, or an alternate (shadow) bitmap
|
||||
maintained by the subclass.
|
||||
*/
|
||||
virtual const SkBitmap& onAccessBitmap() = 0;
|
||||
virtual const SkBitmap& onAccessBitmap(SkBitmap*);
|
||||
|
||||
SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
|
||||
// just for subclasses, to assign a custom pixelref
|
||||
SkPixelRef* setPixelRef(SkPixelRef* pr, size_t offset) {
|
||||
fBitmap.setPixelRef(pr, offset);
|
||||
return pr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements readPixels API. The caller will ensure that:
|
||||
@ -327,13 +374,13 @@ protected:
|
||||
*/
|
||||
virtual bool onReadPixels(const SkBitmap& bitmap,
|
||||
int x, int y,
|
||||
SkCanvas::Config8888 config8888) = 0;
|
||||
SkCanvas::Config8888 config8888);
|
||||
|
||||
/** Called when this device is installed into a Canvas. Balanced by a call
|
||||
/** Called when this device is installed into a Canvas. Balanaced by a call
|
||||
to unlockPixels() when the device is removed from a Canvas.
|
||||
*/
|
||||
virtual void lockPixels() = 0;
|
||||
virtual void unlockPixels() = 0;
|
||||
virtual void lockPixels();
|
||||
virtual void unlockPixels();
|
||||
|
||||
/**
|
||||
* Returns true if the device allows processing of this imagefilter. If
|
||||
@ -341,7 +388,7 @@ protected:
|
||||
* some subclasses that do not support pixel manipulations after drawing
|
||||
* has occurred (e.g. printing). The default implementation returns true.
|
||||
*/
|
||||
virtual bool allowImageFilter(const SkImageFilter*) = 0;
|
||||
virtual bool allowImageFilter(SkImageFilter*);
|
||||
|
||||
/**
|
||||
* Override and return true for filters that the device can handle
|
||||
@ -350,7 +397,7 @@ protected:
|
||||
* Returning false means the SkCanvas will have apply the filter itself,
|
||||
* and just pass the resulting image to the device.
|
||||
*/
|
||||
virtual bool canHandleImageFilter(const SkImageFilter*) = 0;
|
||||
virtual bool canHandleImageFilter(SkImageFilter*);
|
||||
|
||||
/**
|
||||
* Related (but not required) to canHandleImageFilter, this method returns
|
||||
@ -359,25 +406,13 @@ protected:
|
||||
* If the device does not recognize or support this filter,
|
||||
* it just returns false and leaves result and offset unchanged.
|
||||
*/
|
||||
virtual bool filterImage(const SkImageFilter*, const SkBitmap&, const SkMatrix&,
|
||||
SkBitmap* result, SkIPoint* offset) = 0;
|
||||
virtual bool filterImage(SkImageFilter*, const SkBitmap&, const SkMatrix&,
|
||||
SkBitmap* result, SkIPoint* offset);
|
||||
|
||||
// This is equal kBGRA_Premul_Config8888 or kRGBA_Premul_Config8888 if
|
||||
// either is identical to kNative_Premul_Config8888. Otherwise, -1.
|
||||
static const SkCanvas::Config8888 kPMColorAlias;
|
||||
|
||||
protected:
|
||||
// default impl returns NULL
|
||||
virtual SkSurface* newSurface(const SkImageInfo&);
|
||||
|
||||
/**
|
||||
* Leaky properties are those which the device should be applying but it isn't.
|
||||
* These properties will be applied by the draw, when and as it can.
|
||||
* If the device does handle a property, that property should be set to the identity value
|
||||
* for that property, effectively making it non-leaky.
|
||||
*/
|
||||
SkDeviceProperties fLeakyProperties;
|
||||
|
||||
private:
|
||||
friend class SkCanvas;
|
||||
friend struct DeviceCM; //for setMatrixClip
|
||||
@ -385,37 +420,42 @@ private:
|
||||
friend class SkDrawIter;
|
||||
friend class SkDeviceFilteredPaint;
|
||||
friend class SkDeviceImageFilterProxy;
|
||||
friend class DeferredDevice; // for newSurface
|
||||
|
||||
friend class SkSurface_Raster;
|
||||
|
||||
// used to change the backend's pixels (and possibly config/rowbytes)
|
||||
// but cannot change the width/height, so there should be no change to
|
||||
// any clip information.
|
||||
// TODO: move to SkBitmapDevice
|
||||
virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) = 0;
|
||||
void replaceBitmapBackendForRasterSurface(const SkBitmap&);
|
||||
|
||||
// just called by SkCanvas when built as a layer
|
||||
void setOrigin(int x, int y) { fOrigin.set(x, y); }
|
||||
// just called by SkCanvas for saveLayer
|
||||
SkBaseDevice* createCompatibleDeviceForSaveLayer(SkBitmap::Config config,
|
||||
int width, int height,
|
||||
bool isOpaque);
|
||||
SkDevice* createCompatibleDeviceForSaveLayer(SkBitmap::Config config,
|
||||
int width, int height,
|
||||
bool isOpaque);
|
||||
|
||||
/**
|
||||
* Subclasses should override this to implement createCompatibleDevice.
|
||||
*/
|
||||
virtual SkBaseDevice* onCreateCompatibleDevice(SkBitmap::Config config,
|
||||
int width, int height,
|
||||
bool isOpaque,
|
||||
Usage usage) = 0;
|
||||
virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config,
|
||||
int width, int height,
|
||||
bool isOpaque,
|
||||
Usage usage);
|
||||
|
||||
/** Causes any deferred drawing to the device to be completed.
|
||||
*/
|
||||
virtual void flush() = 0;
|
||||
virtual void flush() {}
|
||||
|
||||
SkBitmap fBitmap;
|
||||
SkIPoint fOrigin;
|
||||
SkMetaData* fMetaData;
|
||||
/**
|
||||
* Leaky properties are those which the device should be applying but it isn't.
|
||||
* These properties will be applied by the draw, when and as it can.
|
||||
* If the device does handle a property, that property should be set to the identity value
|
||||
* for that property, effectively making it non-leaky.
|
||||
*/
|
||||
SkDeviceProperties fLeakyProperties;
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
bool fAttachedToCanvas;
|
@ -46,10 +46,10 @@ struct SkDeviceProperties {
|
||||
};
|
||||
|
||||
Orientation getOrientation() {
|
||||
return static_cast<Orientation>(fGeometry & kOrientationMask);
|
||||
return static_cast<Orientation>(fGeometry | kOrientationMask);
|
||||
}
|
||||
Layout getLayout() {
|
||||
return static_cast<Layout>(fGeometry & kLayoutMask);
|
||||
return static_cast<Layout>(fGeometry | kLayoutMask);
|
||||
}
|
||||
|
||||
bool isOrientationKnown() {
|
@ -10,21 +10,20 @@
|
||||
#ifndef SkDraw_DEFINED
|
||||
#define SkDraw_DEFINED
|
||||
|
||||
#include "SkBitmap.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkMask.h"
|
||||
#include "SkMatrix.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkRect.h"
|
||||
|
||||
class SkBitmap;
|
||||
class SkBounder;
|
||||
class SkClipStack;
|
||||
class SkBaseDevice;
|
||||
class SkMatrix;
|
||||
class SkDevice;
|
||||
class SkPath;
|
||||
class SkRegion;
|
||||
class SkRasterClip;
|
||||
struct SkDrawProcs;
|
||||
struct SkRect;
|
||||
class SkRRect;
|
||||
|
||||
class SkDraw {
|
||||
public:
|
||||
@ -35,7 +34,6 @@ public:
|
||||
void drawPoints(SkCanvas::PointMode, size_t count, const SkPoint[],
|
||||
const SkPaint&, bool forceUseDevice = false) const;
|
||||
void drawRect(const SkRect&, const SkPaint&) const;
|
||||
void drawRRect(const SkRRect&, const SkPaint&) const;
|
||||
/**
|
||||
* To save on mallocs, we allow a flag that tells us that srcPath is
|
||||
* mutable, so that we don't have to make copies of it as we transform it.
|
||||
@ -45,15 +43,8 @@ public:
|
||||
* affect the geometry/rasterization, then the pre matrix can just be
|
||||
* pre-concated with the current matrix.
|
||||
*/
|
||||
void drawPath(const SkPath& path, const SkPaint& paint,
|
||||
const SkMatrix* prePathMatrix, bool pathIsMutable) const {
|
||||
this->drawPath(path, paint, prePathMatrix, pathIsMutable, false);
|
||||
}
|
||||
|
||||
void drawPath(const SkPath& path, const SkPaint& paint) const {
|
||||
this->drawPath(path, paint, NULL, false, false);
|
||||
}
|
||||
|
||||
void drawPath(const SkPath& srcPath, const SkPaint&,
|
||||
const SkMatrix* prePathMatrix, bool pathIsMutable) const;
|
||||
void drawBitmap(const SkBitmap&, const SkMatrix&, const SkPaint&) const;
|
||||
void drawSprite(const SkBitmap&, int x, int y, const SkPaint&) const;
|
||||
void drawText(const char text[], size_t byteLength, SkScalar x,
|
||||
@ -63,20 +54,19 @@ public:
|
||||
int scalarsPerPosition, const SkPaint& paint) const;
|
||||
void drawTextOnPath(const char text[], size_t byteLength,
|
||||
const SkPath&, const SkMatrix*, const SkPaint&) const;
|
||||
#ifdef SK_BUILD_FOR_ANDROID
|
||||
void drawPosTextOnPath(const char text[], size_t byteLength,
|
||||
const SkPoint pos[], const SkPaint& paint,
|
||||
const SkPath& path, const SkMatrix* matrix) const;
|
||||
#endif
|
||||
void drawVertices(SkCanvas::VertexMode mode, int count,
|
||||
const SkPoint vertices[], const SkPoint textures[],
|
||||
const SkColor colors[], SkXfermode* xmode,
|
||||
const uint16_t indices[], int ptCount,
|
||||
const SkPaint& paint) const;
|
||||
|
||||
/**
|
||||
* Overwrite the target with the path's coverage (i.e. its mask).
|
||||
* Will overwrite the entire device, so it need not be zero'd first.
|
||||
*
|
||||
* Only device A8 is supported right now.
|
||||
*/
|
||||
void drawPathCoverage(const SkPath& src, const SkPaint& paint) const {
|
||||
this->drawPath(src, paint, NULL, false, true);
|
||||
void drawPath(const SkPath& src, const SkPaint& paint) const {
|
||||
this->drawPath(src, paint, NULL, false);
|
||||
}
|
||||
|
||||
/** Helper function that creates a mask from a path and an optional maskfilter.
|
||||
@ -107,20 +97,12 @@ public:
|
||||
static RectType ComputeRectType(const SkPaint&, const SkMatrix&,
|
||||
SkPoint* strokeSize);
|
||||
|
||||
static bool ShouldDrawTextAsPaths(const SkPaint&, const SkMatrix&);
|
||||
void drawText_asPaths(const char text[], size_t byteLength,
|
||||
SkScalar x, SkScalar y, const SkPaint&) const;
|
||||
void drawPosText_asPaths(const char text[], size_t byteLength,
|
||||
const SkScalar pos[], SkScalar constY,
|
||||
int scalarsPerPosition, const SkPaint&) const;
|
||||
|
||||
private:
|
||||
void drawText_asPaths(const char text[], size_t byteLength,
|
||||
SkScalar x, SkScalar y, const SkPaint&) const;
|
||||
void drawDevMask(const SkMask& mask, const SkPaint&) const;
|
||||
void drawBitmapAsMask(const SkBitmap&, const SkPaint&) const;
|
||||
|
||||
void drawPath(const SkPath&, const SkPaint&, const SkMatrix* preMatrix,
|
||||
bool pathIsMutable, bool drawCoverage) const;
|
||||
|
||||
/**
|
||||
* Return the current clip bounds, in local coordinates, with slop to account
|
||||
* for antialiasing or hairlines (i.e. device-bounds outset by 1, and then
|
||||
@ -139,7 +121,7 @@ public:
|
||||
const SkRasterClip* fRC; // required
|
||||
|
||||
const SkClipStack* fClipStack; // optional
|
||||
SkBaseDevice* fDevice; // optional
|
||||
SkDevice* fDevice; // optional
|
||||
SkBounder* fBounder; // optional
|
||||
SkDrawProcs* fProcs; // optional
|
||||
|
@ -31,7 +31,6 @@ public:
|
||||
kLine_Type,
|
||||
kBitmap_Type,
|
||||
kRect_Type,
|
||||
kRRect_Type,
|
||||
kOval_Type,
|
||||
kPath_Type,
|
||||
kText_Type,
|
@ -64,11 +64,10 @@ public:
|
||||
const SkRect& src, SkRect* dst);
|
||||
|
||||
SkDEVCODE(virtual void toString(SkString* str) const = 0;)
|
||||
SK_DEFINE_FLATTENABLE_TYPE(SkDrawLooper)
|
||||
|
||||
protected:
|
||||
SkDrawLooper() {}
|
||||
SkDrawLooper(SkReadBuffer& buffer) : INHERITED(buffer) {}
|
||||
SkDrawLooper(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
|
||||
|
||||
private:
|
||||
typedef SkFlattenable INHERITED;
|
@ -34,7 +34,7 @@ public:
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkEmptyShader)
|
||||
|
||||
protected:
|
||||
SkEmptyShader(SkReadBuffer& buffer) : INHERITED(buffer) {}
|
||||
SkEmptyShader(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
|
||||
|
||||
private:
|
||||
typedef SkShader INHERITED;
|
@ -65,7 +65,7 @@ template<uint32_t N> struct SkTEndianSwap32 {
|
||||
(N >> 24);
|
||||
};
|
||||
|
||||
/** Vector version of SkEndianSwap32(), which swaps the
|
||||
/** Vector version of SkEndianSwap16(), which swaps the
|
||||
bytes of each value in the array.
|
||||
*/
|
||||
static inline void SkEndianSwap32s(uint32_t array[], int count) {
|
||||
@ -77,70 +77,26 @@ static inline void SkEndianSwap32s(uint32_t array[], int count) {
|
||||
}
|
||||
}
|
||||
|
||||
/** Reverse all 8 bytes in a 64bit value.
|
||||
e.g. 0x1122334455667788 -> 0x8877665544332211
|
||||
*/
|
||||
static inline uint64_t SkEndianSwap64(uint64_t value) {
|
||||
return (((value & 0x00000000000000FFULL) << (8*7)) |
|
||||
((value & 0x000000000000FF00ULL) << (8*5)) |
|
||||
((value & 0x0000000000FF0000ULL) << (8*3)) |
|
||||
((value & 0x00000000FF000000ULL) << (8*1)) |
|
||||
((value & 0x000000FF00000000ULL) >> (8*1)) |
|
||||
((value & 0x0000FF0000000000ULL) >> (8*3)) |
|
||||
((value & 0x00FF000000000000ULL) >> (8*5)) |
|
||||
((value) >> (8*7)));
|
||||
}
|
||||
template<uint64_t N> struct SkTEndianSwap64 {
|
||||
static const uint64_t value = (((N & 0x00000000000000FFULL) << (8*7)) |
|
||||
((N & 0x000000000000FF00ULL) << (8*5)) |
|
||||
((N & 0x0000000000FF0000ULL) << (8*3)) |
|
||||
((N & 0x00000000FF000000ULL) << (8*1)) |
|
||||
((N & 0x000000FF00000000ULL) >> (8*1)) |
|
||||
((N & 0x0000FF0000000000ULL) >> (8*3)) |
|
||||
((N & 0x00FF000000000000ULL) >> (8*5)) |
|
||||
((N) >> (8*7)));
|
||||
};
|
||||
|
||||
/** Vector version of SkEndianSwap64(), which swaps the
|
||||
bytes of each value in the array.
|
||||
*/
|
||||
static inline void SkEndianSwap64s(uint64_t array[], int count) {
|
||||
SkASSERT(count == 0 || array != NULL);
|
||||
|
||||
while (--count >= 0) {
|
||||
*array = SkEndianSwap64(*array);
|
||||
array += 1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SK_CPU_LENDIAN
|
||||
#define SkEndian_SwapBE16(n) SkEndianSwap16(n)
|
||||
#define SkEndian_SwapBE32(n) SkEndianSwap32(n)
|
||||
#define SkEndian_SwapBE64(n) SkEndianSwap64(n)
|
||||
#define SkEndian_SwapLE16(n) (n)
|
||||
#define SkEndian_SwapLE32(n) (n)
|
||||
#define SkEndian_SwapLE64(n) (n)
|
||||
|
||||
#define SkTEndian_SwapBE16(n) SkTEndianSwap16<n>::value
|
||||
#define SkTEndian_SwapBE32(n) SkTEndianSwap32<n>::value
|
||||
#define SkTEndian_SwapBE64(n) SkTEndianSwap64<n>::value
|
||||
#define SkTEndian_SwapLE16(n) (n)
|
||||
#define SkTEndian_SwapLE32(n) (n)
|
||||
#define SkTEndian_SwapLE64(n) (n)
|
||||
#else // SK_CPU_BENDIAN
|
||||
#define SkEndian_SwapBE16(n) (n)
|
||||
#define SkEndian_SwapBE32(n) (n)
|
||||
#define SkEndian_SwapBE64(n) (n)
|
||||
#define SkEndian_SwapLE16(n) SkEndianSwap16(n)
|
||||
#define SkEndian_SwapLE32(n) SkEndianSwap32(n)
|
||||
#define SkEndian_SwapLE64(n) SkEndianSwap64(n)
|
||||
|
||||
#define SkTEndian_SwapBE16(n) (n)
|
||||
#define SkTEndian_SwapBE32(n) (n)
|
||||
#define SkTEndian_SwapBE64(n) (n)
|
||||
#define SkTEndian_SwapLE16(n) SkTEndianSwap16<n>::value
|
||||
#define SkTEndian_SwapLE32(n) SkTEndianSwap32<n>::value
|
||||
#define SkTEndian_SwapLE64(n) SkTEndianSwap64<n>::value
|
||||
#endif
|
||||
|
||||
// When a bytestream is embedded in a 32-bit word, how far we need to
|
@ -1,3 +1,4 @@
|
||||
|
||||
/*
|
||||
* Copyright 2006 The Android Open Source Project
|
||||
*
|
||||
@ -5,6 +6,7 @@
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SkFixed_DEFINED
|
||||
#define SkFixed_DEFINED
|
||||
|
||||
@ -53,6 +55,16 @@ typedef int32_t SkFixed;
|
||||
#define SkFixedToDouble(x) ((x) * 1.5258789e-5)
|
||||
#define SkDoubleToFixed(x) ((SkFixed)((x) * SK_Fixed1))
|
||||
|
||||
/** 32 bit signed integer used to represent fractions values with 30 bits to the right of the decimal point
|
||||
*/
|
||||
typedef int32_t SkFract;
|
||||
#define SK_Fract1 (1 << 30)
|
||||
#define Sk_FracHalf (1 << 29)
|
||||
#define SK_FractPIOver180 (0x11DF46A)
|
||||
|
||||
#define SkFractToFloat(x) ((float)(x) * 0.00000000093132257f)
|
||||
#define SkFloatToFract(x) ((SkFract)((x) * SK_Fract1))
|
||||
|
||||
/** Converts an integer to a SkFixed, asserting that the result does not overflow
|
||||
a 32 bit signed integer
|
||||
*/
|
||||
@ -67,6 +79,31 @@ typedef int32_t SkFixed;
|
||||
#define SkIntToFixed(n) (SkFixed)((n) << 16)
|
||||
#endif
|
||||
|
||||
/** Converts a SkFixed to a SkFract, asserting that the result does not overflow
|
||||
a 32 bit signed integer
|
||||
*/
|
||||
#ifdef SK_DEBUG
|
||||
inline SkFract SkFixedToFract(SkFixed x)
|
||||
{
|
||||
SkASSERT(x >= (-2 << 16) && x <= (2 << 16) - 1);
|
||||
return x << 14;
|
||||
}
|
||||
#else
|
||||
#define SkFixedToFract(x) ((x) << 14)
|
||||
#endif
|
||||
|
||||
/** Returns the signed fraction of a SkFixed
|
||||
*/
|
||||
inline SkFixed SkFixedFraction(SkFixed x)
|
||||
{
|
||||
SkFixed mask = x >> 31 << 16;
|
||||
return (x & 0xFFFF) | mask;
|
||||
}
|
||||
|
||||
/** Converts a SkFract to a SkFixed
|
||||
*/
|
||||
#define SkFractToFixed(x) ((x) >> 14)
|
||||
|
||||
#define SkFixedRoundToInt(x) (((x) + SK_FixedHalf) >> 16)
|
||||
#define SkFixedCeilToInt(x) (((x) + SK_Fixed1 - 1) >> 16)
|
||||
#define SkFixedFloorToInt(x) ((x) >> 16)
|
||||
@ -75,24 +112,62 @@ typedef int32_t SkFixed;
|
||||
#define SkFixedCeilToFixed(x) (((x) + SK_Fixed1 - 1) & 0xFFFF0000)
|
||||
#define SkFixedFloorToFixed(x) ((x) & 0xFFFF0000)
|
||||
|
||||
// DEPRECATED
|
||||
#define SkFixedFloor(x) SkFixedFloorToInt(x)
|
||||
#define SkFixedCeil(x) SkFixedCeilToInt(x)
|
||||
#define SkFixedRound(x) SkFixedRoundToInt(x)
|
||||
|
||||
#define SkFixedAbs(x) SkAbs32(x)
|
||||
#define SkFixedAve(a, b) (((a) + (b)) >> 1)
|
||||
|
||||
SkFixed SkFixedMul_portable(SkFixed, SkFixed);
|
||||
SkFract SkFractMul_portable(SkFract, SkFract);
|
||||
inline SkFixed SkFixedSquare_portable(SkFixed value)
|
||||
{
|
||||
uint32_t a = SkAbs32(value);
|
||||
uint32_t ah = a >> 16;
|
||||
uint32_t al = a & 0xFFFF;
|
||||
SkFixed result = ah * a + al * ah + (al * al >> 16);
|
||||
if (result >= 0)
|
||||
return result;
|
||||
else // Overflow.
|
||||
return SK_FixedMax;
|
||||
}
|
||||
|
||||
#define SkFixedDiv(numer, denom) SkDivBits(numer, denom, 16)
|
||||
SkFixed SkFixedDivInt(int32_t numer, int32_t denom);
|
||||
SkFixed SkFixedMod(SkFixed numer, SkFixed denom);
|
||||
#define SkFixedInvert(n) SkDivBits(SK_Fixed1, n, 16)
|
||||
SkFixed SkFixedFastInvert(SkFixed n);
|
||||
#define SkFixedSqrt(n) SkSqrtBits(n, 23)
|
||||
SkFixed SkFixedMean(SkFixed a, SkFixed b); //*< returns sqrt(x*y)
|
||||
int SkFixedMulCommon(SkFixed, int , int bias); // internal used by SkFixedMulFloor, SkFixedMulCeil, SkFixedMulRound
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// TODO: move fixed sin/cos into SkCosineMapper, as that is the only caller
|
||||
// or rewrite SkCosineMapper to not use it at all
|
||||
#define SkFractDiv(numer, denom) SkDivBits(numer, denom, 30)
|
||||
#define SkFractSqrt(n) SkSqrtBits(n, 30)
|
||||
|
||||
SkFixed SkFixedSinCos(SkFixed radians, SkFixed* cosValueOrNull);
|
||||
#define SkFixedSin(radians) SkFixedSinCos(radians, NULL)
|
||||
static inline SkFixed SkFixedCos(SkFixed radians) {
|
||||
inline SkFixed SkFixedCos(SkFixed radians)
|
||||
{
|
||||
SkFixed cosValue;
|
||||
(void)SkFixedSinCos(radians, &cosValue);
|
||||
return cosValue;
|
||||
}
|
||||
SkFixed SkFixedTan(SkFixed radians);
|
||||
SkFixed SkFixedASin(SkFixed);
|
||||
SkFixed SkFixedACos(SkFixed);
|
||||
SkFixed SkFixedATan2(SkFixed y, SkFixed x);
|
||||
SkFixed SkFixedExp(SkFixed);
|
||||
SkFixed SkFixedLog(SkFixed);
|
||||
|
||||
#define SK_FixedNearlyZero (SK_Fixed1 >> 12)
|
||||
|
||||
inline bool SkFixedNearlyZero(SkFixed x, SkFixed tolerance = SK_FixedNearlyZero)
|
||||
{
|
||||
SkASSERT(tolerance > 0);
|
||||
return SkAbs32(x) < tolerance;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Now look for ASM overrides for our portable versions (should consider putting this in its own file)
|
||||
@ -100,25 +175,34 @@ static inline SkFixed SkFixedCos(SkFixed radians) {
|
||||
#ifdef SkLONGLONG
|
||||
inline SkFixed SkFixedMul_longlong(SkFixed a, SkFixed b)
|
||||
{
|
||||
return (SkFixed)((int64_t)a * b >> 16);
|
||||
return (SkFixed)((SkLONGLONG)a * b >> 16);
|
||||
}
|
||||
inline SkFract SkFractMul_longlong(SkFract a, SkFract b)
|
||||
{
|
||||
return (SkFixed)((SkLONGLONG)a * b >> 30);
|
||||
}
|
||||
inline SkFixed SkFixedSquare_longlong(SkFixed value)
|
||||
{
|
||||
return (SkFixed)((SkLONGLONG)value * value >> 16);
|
||||
}
|
||||
#define SkFixedMul(a,b) SkFixedMul_longlong(a,b)
|
||||
#define SkFractMul(a,b) SkFractMul_longlong(a,b)
|
||||
#define SkFixedSquare(a) SkFixedSquare_longlong(a)
|
||||
#endif
|
||||
|
||||
#if defined(SK_CPU_ARM)
|
||||
#if defined(SK_CPU_ARM) && !defined(__thumb__)
|
||||
/* This guy does not handle NaN or other obscurities, but is faster than
|
||||
than (int)(x*65536)
|
||||
than (int)(x*65536) when we only have software floats
|
||||
*/
|
||||
inline SkFixed SkFloatToFixed_arm(float x)
|
||||
{
|
||||
int32_t y, z;
|
||||
register int32_t y, z;
|
||||
asm("movs %1, %3, lsl #1 \n"
|
||||
"mov %2, #0x8E \n"
|
||||
"sub %1, %2, %1, lsr #24 \n"
|
||||
"mov %2, %3, lsl #8 \n"
|
||||
"orr %2, %2, #0x80000000 \n"
|
||||
"mov %1, %2, lsr %1 \n"
|
||||
"it cs \n"
|
||||
"rsbcs %1, %1, #0 \n"
|
||||
: "=r"(x), "=&r"(y), "=&r"(z)
|
||||
: "r"(x)
|
||||
@ -128,7 +212,7 @@ static inline SkFixed SkFixedCos(SkFixed radians) {
|
||||
}
|
||||
inline SkFixed SkFixedMul_arm(SkFixed x, SkFixed y)
|
||||
{
|
||||
int32_t t;
|
||||
register int32_t t;
|
||||
asm("smull %0, %2, %1, %3 \n"
|
||||
"mov %0, %0, lsr #16 \n"
|
||||
"orr %0, %0, %2, lsl #16 \n"
|
||||
@ -138,16 +222,54 @@ static inline SkFixed SkFixedCos(SkFixed radians) {
|
||||
);
|
||||
return x;
|
||||
}
|
||||
inline SkFixed SkFixedMulAdd_arm(SkFixed x, SkFixed y, SkFixed a)
|
||||
{
|
||||
register int32_t t;
|
||||
asm("smull %0, %3, %1, %4 \n"
|
||||
"add %0, %2, %0, lsr #16 \n"
|
||||
"add %0, %0, %3, lsl #16 \n"
|
||||
: "=r"(x), "=&r"(y), "=&r"(a), "=r"(t)
|
||||
: "%r"(x), "1"(y), "2"(a)
|
||||
:
|
||||
);
|
||||
return x;
|
||||
}
|
||||
inline SkFixed SkFractMul_arm(SkFixed x, SkFixed y)
|
||||
{
|
||||
register int32_t t;
|
||||
asm("smull %0, %2, %1, %3 \n"
|
||||
"mov %0, %0, lsr #30 \n"
|
||||
"orr %0, %0, %2, lsl #2 \n"
|
||||
: "=r"(x), "=&r"(y), "=r"(t)
|
||||
: "r"(x), "1"(y)
|
||||
:
|
||||
);
|
||||
return x;
|
||||
}
|
||||
#undef SkFixedMul
|
||||
#undef SkFractMul
|
||||
#define SkFixedMul(x, y) SkFixedMul_arm(x, y)
|
||||
#define SkFractMul(x, y) SkFractMul_arm(x, y)
|
||||
#define SkFixedMulAdd(x, y, a) SkFixedMulAdd_arm(x, y, a)
|
||||
|
||||
#undef SkFloatToFixed
|
||||
#define SkFloatToFixed(x) SkFloatToFixed_arm(x)
|
||||
#endif
|
||||
|
||||
/////////////////////// Now define our macros to the portable versions if they weren't overridden
|
||||
|
||||
#ifndef SkFixedSquare
|
||||
#define SkFixedSquare(x) SkFixedSquare_portable(x)
|
||||
#endif
|
||||
#ifndef SkFixedMul
|
||||
#define SkFixedMul(x, y) SkFixedMul_portable(x, y)
|
||||
#endif
|
||||
#ifndef SkFractMul
|
||||
#define SkFractMul(x, y) SkFractMul_portable(x, y)
|
||||
#endif
|
||||
#ifndef SkFixedMulAdd
|
||||
#define SkFixedMulAdd(x, y, a) (SkFixedMul(x, y) + (a))
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -159,6 +281,10 @@ typedef int64_t SkFixed48;
|
||||
#define SkFixed48ToFixed(x) ((SkFixed)((x) >> 32))
|
||||
#define SkFloatToFixed48(x) ((SkFixed48)((x) * (65536.0f * 65536.0f * 65536.0f)))
|
||||
|
||||
#define SkScalarToFixed48(x) SkFloatToFixed48(x)
|
||||
#ifdef SK_SCALAR_IS_FLOAT
|
||||
#define SkScalarToFixed48(x) SkFloatToFixed48(x)
|
||||
#else
|
||||
#define SkScalarToFixed48(x) SkFixedToFixed48(x)
|
||||
#endif
|
||||
|
||||
#endif
|
@ -12,12 +12,11 @@
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
class SkReadBuffer;
|
||||
class SkWriteBuffer;
|
||||
class SkFlattenableReadBuffer;
|
||||
class SkFlattenableWriteBuffer;
|
||||
|
||||
#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \
|
||||
SkFlattenable::Registrar(#flattenable, flattenable::CreateProc, \
|
||||
flattenable::GetFlattenableType());
|
||||
SkFlattenable::Registrar(#flattenable, flattenable::CreateProc);
|
||||
|
||||
#define SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() static void InitializeFlattenables();
|
||||
|
||||
@ -28,22 +27,14 @@ class SkWriteBuffer;
|
||||
}
|
||||
|
||||
#define SK_DECLARE_UNFLATTENABLE_OBJECT() \
|
||||
virtual Factory getFactory() const SK_OVERRIDE { return NULL; }
|
||||
virtual Factory getFactory() SK_OVERRIDE { return NULL; }; \
|
||||
|
||||
#define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable) \
|
||||
virtual Factory getFactory() const SK_OVERRIDE { return CreateProc; } \
|
||||
static SkFlattenable* CreateProc(SkReadBuffer& buffer) { \
|
||||
virtual Factory getFactory() SK_OVERRIDE { return CreateProc; } \
|
||||
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { \
|
||||
return SkNEW_ARGS(flattenable, (buffer)); \
|
||||
}
|
||||
|
||||
/** For SkFlattenable derived objects with a valid type
|
||||
This macro should only be used in base class objects in core
|
||||
*/
|
||||
#define SK_DEFINE_FLATTENABLE_TYPE(flattenable) \
|
||||
static Type GetFlattenableType() { \
|
||||
return k##flattenable##_Type; \
|
||||
}
|
||||
|
||||
/** \class SkFlattenable
|
||||
|
||||
SkFlattenable is the base class for objects that need to be flattened
|
||||
@ -52,22 +43,9 @@ class SkWriteBuffer;
|
||||
*/
|
||||
class SK_API SkFlattenable : public SkRefCnt {
|
||||
public:
|
||||
enum Type {
|
||||
kSkColorFilter_Type,
|
||||
kSkDrawLooper_Type,
|
||||
kSkImageFilter_Type,
|
||||
kSkMaskFilter_Type,
|
||||
kSkPathEffect_Type,
|
||||
kSkPixelRef_Type,
|
||||
kSkRasterizer_Type,
|
||||
kSkShader_Type,
|
||||
kSkUnitMapper_Type,
|
||||
kSkXfermode_Type,
|
||||
};
|
||||
|
||||
SK_DECLARE_INST_COUNT(SkFlattenable)
|
||||
|
||||
typedef SkFlattenable* (*Factory)(SkReadBuffer&);
|
||||
typedef SkFlattenable* (*Factory)(SkFlattenableReadBuffer&);
|
||||
|
||||
SkFlattenable() {}
|
||||
|
||||
@ -75,38 +53,32 @@ public:
|
||||
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
|
||||
*/
|
||||
const char* getTypeName() const { return FactoryToName(getFactory()); }
|
||||
virtual Factory getFactory() = 0;
|
||||
|
||||
static Factory NameToFactory(const char name[]);
|
||||
static const char* FactoryToName(Factory);
|
||||
static bool NameToType(const char name[], Type* type);
|
||||
|
||||
static void Register(const char name[], Factory, Type);
|
||||
static void Register(const char name[], Factory);
|
||||
|
||||
class Registrar {
|
||||
public:
|
||||
Registrar(const char name[], Factory factory, Type type) {
|
||||
SkFlattenable::Register(name, factory, type);
|
||||
Registrar(const char name[], Factory factory) {
|
||||
SkFlattenable::Register(name, factory);
|
||||
}
|
||||
};
|
||||
|
||||
protected:
|
||||
SkFlattenable(SkFlattenableReadBuffer&) {}
|
||||
/** Override this to write data specific to your subclass into the buffer,
|
||||
being sure to call your super-class' version first. This data will later
|
||||
be passed to your Factory function, returned by getFactory().
|
||||
*/
|
||||
virtual void flatten(SkWriteBuffer&) const;
|
||||
|
||||
protected:
|
||||
SkFlattenable(SkReadBuffer&) {}
|
||||
virtual void flatten(SkFlattenableWriteBuffer&) const;
|
||||
|
||||
private:
|
||||
static void InitializeFlattenablesIfNeeded();
|
||||
static void InitializeFlattenables();
|
||||
|
||||
friend class SkGraphics;
|
||||
friend class SkFlattenableWriteBuffer;
|
||||
|
||||
typedef SkRefCnt INHERITED;
|
||||
};
|
175
gfx/skia/include/core/SkFlattenableBuffers.h
Normal file
175
gfx/skia/include/core/SkFlattenableBuffers.h
Normal file
@ -0,0 +1,175 @@
|
||||
|
||||
/*
|
||||
* 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 SkFlattenableBuffers_DEFINED
|
||||
#define SkFlattenableBuffers_DEFINED
|
||||
|
||||
#include "SkColor.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkPoint.h"
|
||||
|
||||
class SkBitmap;
|
||||
class SkFlattenable;
|
||||
struct SkIRect;
|
||||
class SkMatrix;
|
||||
class SkOrderedReadBuffer;
|
||||
class SkOrderedWriteBuffer;
|
||||
class SkPath;
|
||||
class SkPixelRef;
|
||||
struct SkRect;
|
||||
class SkRefCnt;
|
||||
class SkRegion;
|
||||
class SkStream;
|
||||
class SkString;
|
||||
class SkTypeface;
|
||||
class SkWStream;
|
||||
|
||||
class SkFlattenableReadBuffer {
|
||||
public:
|
||||
SkFlattenableReadBuffer();
|
||||
virtual ~SkFlattenableReadBuffer();
|
||||
|
||||
bool isOrderedBinaryBuffer() { return NULL != getOrderedBinaryBuffer(); }
|
||||
virtual SkOrderedReadBuffer* getOrderedBinaryBuffer() { return NULL; }
|
||||
|
||||
enum Flags {
|
||||
kCrossProcess_Flag = 1 << 0,
|
||||
kScalarIsFloat_Flag = 1 << 1,
|
||||
kPtrIs64Bit_Flag = 1 << 2,
|
||||
};
|
||||
|
||||
void setFlags(uint32_t flags) { fFlags = flags; }
|
||||
uint32_t getFlags() const { return fFlags; }
|
||||
|
||||
bool isCrossProcess() const { return SkToBool(fFlags & kCrossProcess_Flag); }
|
||||
bool isScalarFloat() const { return SkToBool(fFlags & kScalarIsFloat_Flag); }
|
||||
bool isPtr64Bit() const { return SkToBool(fFlags & kPtrIs64Bit_Flag); }
|
||||
|
||||
// primitives
|
||||
virtual bool readBool() = 0;
|
||||
virtual SkColor readColor() = 0;
|
||||
virtual SkFixed readFixed() = 0;
|
||||
virtual int32_t readInt() = 0;
|
||||
virtual SkScalar readScalar() = 0;
|
||||
virtual uint32_t readUInt() = 0;
|
||||
virtual int32_t read32() = 0;
|
||||
|
||||
// strings -- the caller is responsible for freeing the string contents
|
||||
virtual char* readString() = 0;
|
||||
virtual void* readEncodedString(size_t* length, SkPaint::TextEncoding encoding) = 0;
|
||||
|
||||
// common data structures
|
||||
virtual SkFlattenable* readFlattenable() = 0;
|
||||
virtual void readPoint(SkPoint* point) = 0;
|
||||
virtual void readMatrix(SkMatrix* matrix) = 0;
|
||||
virtual void readIRect(SkIRect* rect) = 0;
|
||||
virtual void readRect(SkRect* rect) = 0;
|
||||
virtual void readRegion(SkRegion* region) = 0;
|
||||
virtual void readPath(SkPath* path) = 0;
|
||||
|
||||
// binary data and arrays
|
||||
virtual uint32_t readByteArray(void* value) = 0;
|
||||
virtual uint32_t readColorArray(SkColor* colors) = 0;
|
||||
virtual uint32_t readIntArray(int32_t* values) = 0;
|
||||
virtual uint32_t readPointArray(SkPoint* points) = 0;
|
||||
virtual uint32_t readScalarArray(SkScalar* values) = 0;
|
||||
|
||||
/** This helper peeks into the buffer and reports back the length of the next array in
|
||||
* the buffer but does not change the state of the buffer.
|
||||
*/
|
||||
virtual uint32_t getArrayCount() = 0;
|
||||
|
||||
// helper functions
|
||||
virtual void* readFunctionPtr();
|
||||
virtual void readPaint(SkPaint* paint);
|
||||
|
||||
virtual void readBitmap(SkBitmap* bitmap) = 0;
|
||||
virtual SkTypeface* readTypeface() = 0;
|
||||
|
||||
// helper function for classes with const SkPoint members
|
||||
SkPoint readPoint() {
|
||||
SkPoint point;
|
||||
this->readPoint(&point);
|
||||
return point;
|
||||
}
|
||||
|
||||
template <typename T> T* readFlattenableT() {
|
||||
return static_cast<T*>(this->readFlattenable());
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t fFlags;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class SkFlattenableWriteBuffer {
|
||||
public:
|
||||
SkFlattenableWriteBuffer();
|
||||
virtual ~SkFlattenableWriteBuffer();
|
||||
|
||||
virtual bool isOrderedBinaryBuffer() { return false; }
|
||||
virtual SkOrderedWriteBuffer* getOrderedBinaryBuffer() { sk_throw(); return NULL; }
|
||||
|
||||
// primitives
|
||||
virtual void writeByteArray(const void* data, size_t size) = 0;
|
||||
virtual void writeBool(bool value) = 0;
|
||||
virtual void writeFixed(SkFixed value) = 0;
|
||||
virtual void writeScalar(SkScalar value) = 0;
|
||||
virtual void writeScalarArray(const SkScalar* value, uint32_t count) = 0;
|
||||
virtual void writeInt(int32_t value) = 0;
|
||||
virtual void writeIntArray(const int32_t* value, uint32_t count) = 0;
|
||||
virtual void writeUInt(uint32_t value) = 0;
|
||||
virtual void write32(int32_t value) = 0; // printf in hex
|
||||
virtual void writeString(const char* value) = 0;
|
||||
virtual void writeEncodedString(const void* value, size_t byteLength,
|
||||
SkPaint::TextEncoding encoding) = 0;
|
||||
|
||||
// common data structures
|
||||
virtual void writeFlattenable(SkFlattenable* flattenable) = 0;
|
||||
virtual void writeColor(const SkColor& color) = 0;
|
||||
virtual void writeColorArray(const SkColor* color, uint32_t count) = 0;
|
||||
virtual void writePoint(const SkPoint& point) = 0;
|
||||
virtual void writePointArray(const SkPoint* points, uint32_t count) = 0;
|
||||
virtual void writeMatrix(const SkMatrix& matrix) = 0;
|
||||
virtual void writeIRect(const SkIRect& rect) = 0;
|
||||
virtual void writeRect(const SkRect& rect) = 0;
|
||||
virtual void writeRegion(const SkRegion& region) = 0;
|
||||
virtual void writePath(const SkPath& path) = 0;
|
||||
virtual size_t writeStream(SkStream* stream, size_t length) = 0;
|
||||
|
||||
// helper functions
|
||||
virtual void writeFunctionPtr(void* ptr);
|
||||
virtual void writePaint(const SkPaint& paint);
|
||||
|
||||
virtual void writeBitmap(const SkBitmap& bitmap) = 0;
|
||||
virtual void writeTypeface(SkTypeface* typeface) = 0;
|
||||
|
||||
virtual bool writeToStream(SkWStream*) = 0;
|
||||
|
||||
enum Flags {
|
||||
kCrossProcess_Flag = 0x01,
|
||||
};
|
||||
|
||||
uint32_t getFlags() const { return fFlags; }
|
||||
void setFlags(uint32_t flags) { fFlags = flags; }
|
||||
|
||||
bool isCrossProcess() const {
|
||||
return SkToBool(fFlags & kCrossProcess_Flag);
|
||||
}
|
||||
|
||||
bool persistTypeface() const { return (fFlags & kCrossProcess_Flag) != 0; }
|
||||
|
||||
protected:
|
||||
// A helper function so that each subclass does not have to be a friend of SkFlattenable
|
||||
void flattenObject(SkFlattenable* obj, SkFlattenableWriteBuffer& buffer);
|
||||
|
||||
uint32_t fFlags;
|
||||
};
|
||||
|
||||
#endif
|
@ -127,7 +127,12 @@ static inline int32_t SkFloatToIntCeil(float x) {
|
||||
|
||||
// Scalar wrappers for float-bit routines
|
||||
|
||||
#define SkScalarAs2sCompliment(x) SkFloatAs2sCompliment(x)
|
||||
#define Sk2sComplimentAsScalar(x) Sk2sComplimentAsFloat(x)
|
||||
#ifdef SK_SCALAR_IS_FLOAT
|
||||
#define SkScalarAs2sCompliment(x) SkFloatAs2sCompliment(x)
|
||||
#define Sk2sComplimentAsScalar(x) Sk2sComplimentAsFloat(x)
|
||||
#else
|
||||
#define SkScalarAs2sCompliment(x) (x)
|
||||
#define Sk2sComplimentAsScalar(x) (x)
|
||||
#endif
|
||||
|
||||
#endif
|
@ -77,8 +77,6 @@ static inline float sk_float_copysign(float x, float y) {
|
||||
#define sk_float_isinf(x) isinf(x)
|
||||
#endif
|
||||
|
||||
#define sk_double_isnan(a) sk_float_isnan(a)
|
||||
|
||||
#ifdef SK_USE_FLOATBITS
|
||||
#define sk_float_floor2int(x) SkFloatToIntFloor(x)
|
||||
#define sk_float_round2int(x) SkFloatToIntRound(x)
|
||||
@ -96,45 +94,4 @@ extern const uint32_t gIEEENegativeInfinity;
|
||||
#define SK_FloatNaN (*SkTCast<const float*>(&gIEEENotANumber))
|
||||
#define SK_FloatInfinity (*SkTCast<const float*>(&gIEEEInfinity))
|
||||
#define SK_FloatNegativeInfinity (*SkTCast<const float*>(&gIEEENegativeInfinity))
|
||||
|
||||
#if defined(__SSE__)
|
||||
#include <xmmintrin.h>
|
||||
#elif defined(__ARM_NEON__)
|
||||
#include <arm_neon.h>
|
||||
#endif
|
||||
|
||||
// Fast, approximate inverse square root.
|
||||
// Compare to name-brand "1.0f / sk_float_sqrt(x)". Should be around 10x faster on SSE, 2x on NEON.
|
||||
static inline float sk_float_rsqrt(const float x) {
|
||||
// We want all this inlined, so we'll inline SIMD and just take the hit when we don't know we've got
|
||||
// it at compile time. This is going to be too fast to productively hide behind a function pointer.
|
||||
//
|
||||
// We do one step of Newton's method to refine the estimates in the NEON and null paths. No
|
||||
// refinement is faster, but very innacurate. Two steps is more accurate, but slower than 1/sqrt.
|
||||
#if defined(__SSE__)
|
||||
float result;
|
||||
_mm_store_ss(&result, _mm_rsqrt_ss(_mm_set_ss(x)));
|
||||
return result;
|
||||
#elif defined(__ARM_NEON__)
|
||||
// Get initial estimate.
|
||||
const float32x2_t xx = vdup_n_f32(x); // Clever readers will note we're doing everything 2x.
|
||||
float32x2_t estimate = vrsqrte_f32(xx);
|
||||
|
||||
// One step of Newton's method to refine.
|
||||
const float32x2_t estimate_sq = vmul_f32(estimate, estimate);
|
||||
estimate = vmul_f32(estimate, vrsqrts_f32(xx, estimate_sq));
|
||||
return vget_lane_f32(estimate, 0); // 1 will work fine too; the answer's in both places.
|
||||
#else
|
||||
// Get initial estimate.
|
||||
int i = *SkTCast<int*>(&x);
|
||||
i = 0x5f3759df - (i>>1);
|
||||
float estimate = *SkTCast<float*>(&i);
|
||||
|
||||
// One step of Newton's method to refine.
|
||||
const float estimate_sq = estimate*estimate;
|
||||
estimate *= (1.5f-0.5f*x*estimate_sq);
|
||||
return estimate;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
@ -72,12 +72,6 @@ int SkFindQuadExtrema(SkScalar a, SkScalar b, SkScalar c, SkScalar tValues[1]);
|
||||
int SkChopQuadAtYExtrema(const SkPoint src[3], SkPoint dst[5]);
|
||||
int SkChopQuadAtXExtrema(const SkPoint src[3], SkPoint dst[5]);
|
||||
|
||||
/** Given 3 points on a quadratic bezier, if the point of maximum
|
||||
curvature exists on the segment, returns the t value for this
|
||||
point along the curve. Otherwise it will return a value of 0.
|
||||
*/
|
||||
float SkFindQuadMaxCurvature(const SkPoint src[3]);
|
||||
|
||||
/** Given 3 points on a quadratic bezier, divide it into 2 quadratics
|
||||
if the point of maximum curvature exists on the quad segment.
|
||||
Depending on what is returned, dst[] is treated as follows
|
||||
@ -212,96 +206,4 @@ enum SkRotationDirection {
|
||||
int SkBuildQuadArc(const SkVector& unitStart, const SkVector& unitStop,
|
||||
SkRotationDirection, const SkMatrix*, SkPoint quadPoints[]);
|
||||
|
||||
// experimental
|
||||
struct SkConic {
|
||||
SkPoint fPts[3];
|
||||
SkScalar fW;
|
||||
|
||||
void set(const SkPoint pts[3], SkScalar w) {
|
||||
memcpy(fPts, pts, 3 * sizeof(SkPoint));
|
||||
fW = w;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a t-value [0...1] return its position and/or tangent.
|
||||
* If pos is not null, return its position at the t-value.
|
||||
* If tangent is not null, return its tangent at the t-value. NOTE the
|
||||
* tangent value's length is arbitrary, and only its direction should
|
||||
* be used.
|
||||
*/
|
||||
void evalAt(SkScalar t, SkPoint* pos, SkVector* tangent = NULL) const;
|
||||
void chopAt(SkScalar t, SkConic dst[2]) const;
|
||||
void chop(SkConic dst[2]) const;
|
||||
|
||||
void computeAsQuadError(SkVector* err) const;
|
||||
bool asQuadTol(SkScalar tol) const;
|
||||
|
||||
/**
|
||||
* return the power-of-2 number of quads needed to approximate this conic
|
||||
* with a sequence of quads. Will be >= 0.
|
||||
*/
|
||||
int computeQuadPOW2(SkScalar tol) const;
|
||||
|
||||
/**
|
||||
* Chop this conic into N quads, stored continguously in pts[], where
|
||||
* N = 1 << pow2. The amount of storage needed is (1 + 2 * N)
|
||||
*/
|
||||
int chopIntoQuadsPOW2(SkPoint pts[], int pow2) const;
|
||||
|
||||
bool findXExtrema(SkScalar* t) const;
|
||||
bool findYExtrema(SkScalar* t) const;
|
||||
bool chopAtXExtrema(SkConic dst[2]) const;
|
||||
bool chopAtYExtrema(SkConic dst[2]) const;
|
||||
|
||||
void computeTightBounds(SkRect* bounds) const;
|
||||
void computeFastBounds(SkRect* bounds) const;
|
||||
};
|
||||
|
||||
#include "SkTemplates.h"
|
||||
|
||||
/**
|
||||
* Help class to allocate storage for approximating a conic with N quads.
|
||||
*/
|
||||
class SkAutoConicToQuads {
|
||||
public:
|
||||
SkAutoConicToQuads() : fQuadCount(0) {}
|
||||
|
||||
/**
|
||||
* Given a conic and a tolerance, return the array of points for the
|
||||
* approximating quad(s). Call countQuads() to know the number of quads
|
||||
* represented in these points.
|
||||
*
|
||||
* The quads are allocated to share end-points. e.g. if there are 4 quads,
|
||||
* there will be 9 points allocated as follows
|
||||
* quad[0] == pts[0..2]
|
||||
* quad[1] == pts[2..4]
|
||||
* quad[2] == pts[4..6]
|
||||
* quad[3] == pts[6..8]
|
||||
*/
|
||||
const SkPoint* computeQuads(const SkConic& conic, SkScalar tol) {
|
||||
int pow2 = conic.computeQuadPOW2(tol);
|
||||
fQuadCount = 1 << pow2;
|
||||
SkPoint* pts = fStorage.reset(1 + 2 * fQuadCount);
|
||||
conic.chopIntoQuadsPOW2(pts, pow2);
|
||||
return pts;
|
||||
}
|
||||
|
||||
const SkPoint* computeQuads(const SkPoint pts[3], SkScalar weight,
|
||||
SkScalar tol) {
|
||||
SkConic conic;
|
||||
conic.set(pts, weight);
|
||||
return computeQuads(conic, tol);
|
||||
}
|
||||
|
||||
int countQuads() const { return fQuadCount; }
|
||||
|
||||
private:
|
||||
enum {
|
||||
kQuadCount = 8, // should handle most conics
|
||||
kPointCount = 1 + 2 * kQuadCount,
|
||||
};
|
||||
SkAutoSTMalloc<kPointCount, SkPoint> fStorage;
|
||||
int fQuadCount; // #quads for current usage
|
||||
};
|
||||
|
||||
#endif
|
@ -53,25 +53,6 @@ public:
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* For debugging purposes, this will attempt to purge the font cache. It
|
||||
* does not change the limit, but will cause subsequent font measures and
|
||||
@ -79,10 +60,6 @@ public:
|
||||
*/
|
||||
static void PurgeFontCache();
|
||||
|
||||
static size_t GetImageCacheBytesUsed();
|
||||
static size_t GetImageCacheByteLimit();
|
||||
static size_t SetImageCacheByteLimit(size_t newLimit);
|
||||
|
||||
/**
|
||||
* Applications with command line options may pass optional state, such
|
||||
* as cache sizes, here, for instance:
|
100
gfx/skia/include/core/SkImage.h
Normal file
100
gfx/skia/include/core/SkImage.h
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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 "SkRefCnt.h"
|
||||
#include "SkScalar.h"
|
||||
|
||||
class SkData;
|
||||
class SkCanvas;
|
||||
class SkPaint;
|
||||
class SkShader;
|
||||
class GrContext;
|
||||
class GrTexture;
|
||||
|
||||
// need for TileMode
|
||||
#include "SkShader.h"
|
||||
|
||||
////// EXPERIMENTAL
|
||||
|
||||
/**
|
||||
* SkImage is an abstraction for drawing a rectagle of pixels, though the
|
||||
* particular type of image could be actually storing its data on the GPU, or
|
||||
* as drawing commands (picture or PDF or otherwise), ready to be played back
|
||||
* into another canvas.
|
||||
*
|
||||
* The content of SkImage is always immutable, though the actual storage may
|
||||
* change, if for example that image can be re-created via encoded data or
|
||||
* other means.
|
||||
*/
|
||||
class SkImage : public SkRefCnt {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkImage)
|
||||
|
||||
enum ColorType {
|
||||
kAlpha_8_ColorType,
|
||||
kRGB_565_ColorType,
|
||||
kRGBA_8888_ColorType,
|
||||
kBGRA_8888_ColorType,
|
||||
kPMColor_ColorType,
|
||||
|
||||
kLastEnum_ColorType = kPMColor_ColorType
|
||||
};
|
||||
|
||||
enum AlphaType {
|
||||
kIgnore_AlphaType,
|
||||
kOpaque_AlphaType,
|
||||
kPremul_AlphaType,
|
||||
kUnpremul_AlphaType,
|
||||
|
||||
kLastEnum_AlphaType = kUnpremul_AlphaType
|
||||
};
|
||||
|
||||
struct Info {
|
||||
int fWidth;
|
||||
int fHeight;
|
||||
ColorType fColorType;
|
||||
AlphaType fAlphaType;
|
||||
};
|
||||
|
||||
static SkImage* NewRasterCopy(const Info&, const void* pixels, size_t rowBytes);
|
||||
static SkImage* NewRasterData(const Info&, SkData* pixels, size_t rowBytes);
|
||||
static SkImage* NewEncodedData(SkData*);
|
||||
static SkImage* NewTexture(GrTexture*);
|
||||
|
||||
int width() const { return fWidth; }
|
||||
int height() const { return fHeight; }
|
||||
uint32_t uniqueID() const { return fUniqueID; }
|
||||
|
||||
SkShader* newShaderClamp() const;
|
||||
SkShader* newShader(SkShader::TileMode, SkShader::TileMode) const;
|
||||
|
||||
void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*);
|
||||
|
||||
protected:
|
||||
SkImage(int width, int height) :
|
||||
fWidth(width),
|
||||
fHeight(height),
|
||||
fUniqueID(NextUniqueID()) {
|
||||
|
||||
SkASSERT(width >= 0);
|
||||
SkASSERT(height >= 0);
|
||||
}
|
||||
|
||||
private:
|
||||
const int fWidth;
|
||||
const int fHeight;
|
||||
const uint32_t fUniqueID;
|
||||
|
||||
static uint32_t NextUniqueID();
|
||||
|
||||
typedef SkRefCnt INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
171
gfx/skia/include/core/SkImageFilter.h
Normal file
171
gfx/skia/include/core/SkImageFilter.h
Normal file
@ -0,0 +1,171 @@
|
||||
/*
|
||||
* 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 "SkFlattenable.h"
|
||||
|
||||
class SkBitmap;
|
||||
class SkColorFilter;
|
||||
class SkDevice;
|
||||
class SkMatrix;
|
||||
struct SkIPoint;
|
||||
struct SkIRect;
|
||||
class SkShader;
|
||||
class GrEffectRef;
|
||||
class GrTexture;
|
||||
|
||||
/**
|
||||
* Experimental.
|
||||
*
|
||||
* 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).
|
||||
*
|
||||
* THIS SIGNATURE IS TEMPORARY
|
||||
*
|
||||
* There are several weaknesses in this function signature:
|
||||
* 1. Does not expose the destination/target device, so filters that can draw
|
||||
* directly to it are unable to take advantage of that optimization.
|
||||
* 2. Does not expose a way to create a "compabitible" image (i.e. gpu -> gpu)
|
||||
* 3. As with #1, the filter is unable to "read" the dest (which would be slow)
|
||||
*
|
||||
* Therefore, we should not create any real dependencies on this API yet -- it
|
||||
* is being checked in as a check-point so we can explore these and other
|
||||
* considerations.
|
||||
*/
|
||||
class SK_API SkImageFilter : public SkFlattenable {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkImageFilter)
|
||||
|
||||
class Proxy {
|
||||
public:
|
||||
virtual ~Proxy() {};
|
||||
|
||||
virtual SkDevice* createDevice(int width, int height) = 0;
|
||||
// returns true if the proxy can handle this filter natively
|
||||
virtual bool canHandleImageFilter(SkImageFilter*) = 0;
|
||||
// returns true if the proxy handled the filter itself. if this returns
|
||||
// false then the filter's code will be called.
|
||||
virtual bool filterImage(SkImageFilter*, const SkBitmap& src,
|
||||
const SkMatrix& ctm,
|
||||
SkBitmap* result, SkIPoint* offset) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Request a new (result) image to be created from the src image.
|
||||
* If the src has no pixels (isNull()) then the request just wants to
|
||||
* receive the config and width/height of the result.
|
||||
*
|
||||
* The matrix is the current matrix on the canvas.
|
||||
*
|
||||
* Offset is the amount to translate the resulting image relative to the
|
||||
* src when it is drawn.
|
||||
*
|
||||
* If the result image cannot be created, return false, in which case both
|
||||
* the result and offset parameters will be ignored by the caller.
|
||||
*/
|
||||
bool filterImage(Proxy*, const SkBitmap& src, const SkMatrix& ctm,
|
||||
SkBitmap* result, SkIPoint* offset);
|
||||
|
||||
/**
|
||||
* Given the src bounds of an image, this returns the bounds of the result
|
||||
* image after the filter has been applied.
|
||||
*/
|
||||
bool filterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst);
|
||||
|
||||
/**
|
||||
* Returns true if the filter can be expressed a single-pass
|
||||
* GrEffect, used to process this filter on the GPU, or false if
|
||||
* not.
|
||||
*
|
||||
* If effect is non-NULL, a new GrEffect instance is stored
|
||||
* in it. The caller assumes ownership of the stage, and it is up to the
|
||||
* caller to unref it.
|
||||
*
|
||||
* The effect can assume its vertexCoords space maps 1-to-1 with texels
|
||||
* in the texture.
|
||||
*/
|
||||
virtual bool asNewEffect(GrEffectRef** effect, GrTexture*) const;
|
||||
|
||||
/**
|
||||
* Returns true if the filter can be processed on the GPU. This is most
|
||||
* often used for multi-pass effects, where intermediate results must be
|
||||
* rendered to textures. For single-pass effects, use asNewEffect().
|
||||
* The default implementation returns false.
|
||||
*/
|
||||
virtual bool canFilterImageGPU() const;
|
||||
|
||||
/**
|
||||
* Process this image filter on the GPU. src is the source image for
|
||||
* processing, as a texture-backed bitmap. result is the destination
|
||||
* bitmap, which should contain a texture-backed pixelref on success.
|
||||
* The default implementation returns returns false and ignores the
|
||||
* result parameter.
|
||||
*/
|
||||
virtual bool filterImageGPU(Proxy*, const SkBitmap& src, SkBitmap* result);
|
||||
|
||||
/**
|
||||
* 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).
|
||||
*/
|
||||
virtual bool asColorFilter(SkColorFilter** filterPtr) const;
|
||||
|
||||
/**
|
||||
* Returns the number of inputs this filter will accept (some inputs can
|
||||
* be NULL).
|
||||
*/
|
||||
int countInputs() const { return fInputCount; }
|
||||
|
||||
/**
|
||||
* Returns the input filter at a given index, or NULL if no input is
|
||||
* connected. The indices used are filter-specific.
|
||||
*/
|
||||
SkImageFilter* getInput(int i) const {
|
||||
SkASSERT(i < fInputCount);
|
||||
return fInputs[i];
|
||||
}
|
||||
|
||||
protected:
|
||||
SkImageFilter(int inputCount, SkImageFilter** inputs);
|
||||
|
||||
// Convenience constructor for 1-input filters.
|
||||
explicit SkImageFilter(SkImageFilter* input);
|
||||
|
||||
// Convenience constructor for 2-input filters.
|
||||
SkImageFilter(SkImageFilter* input1, SkImageFilter* input2);
|
||||
|
||||
virtual ~SkImageFilter();
|
||||
|
||||
explicit SkImageFilter(SkFlattenableReadBuffer& rb);
|
||||
|
||||
virtual void flatten(SkFlattenableWriteBuffer& wb) const SK_OVERRIDE;
|
||||
|
||||
// Default impl returns false
|
||||
virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
|
||||
SkBitmap* result, SkIPoint* offset);
|
||||
// Default impl copies src into dst and returns true
|
||||
virtual bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*);
|
||||
|
||||
// Return the result of processing the given input, or the source bitmap
|
||||
// if we have no connected input at that index.
|
||||
SkBitmap getInputResult(int index, Proxy*, const SkBitmap& src, const SkMatrix&,
|
||||
SkIPoint*);
|
||||
|
||||
private:
|
||||
typedef SkFlattenable INHERITED;
|
||||
int fInputCount;
|
||||
SkImageFilter** fInputs;
|
||||
};
|
||||
|
||||
#endif
|
39
gfx/skia/include/core/SkImageTypes.h
Normal file
39
gfx/skia/include/core/SkImageTypes.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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 SkImageTypes_DEFINED
|
||||
#define SkImageTypes_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
enum SkColorType {
|
||||
kAlpha_8_SkColorType,
|
||||
kRGB_565_SkColorType,
|
||||
// kRGBA_8888_SkColorType,
|
||||
// kBGRA_8888_SkColorType,
|
||||
kPMColor_SkColorType,
|
||||
|
||||
kLastEnum_SkColorType = kPMColor_SkColorType
|
||||
};
|
||||
|
||||
enum SkAlphaType {
|
||||
// kIgnore_SkAlphaType,
|
||||
kOpaque_SkAlphaType,
|
||||
// kUnpremul_SkAlphaType,
|
||||
kPremul_SkAlphaType,
|
||||
|
||||
kLastEnum_SkAlphaType = kPremul_SkAlphaType
|
||||
};
|
||||
|
||||
struct SkImageInfo {
|
||||
int fWidth;
|
||||
int fHeight;
|
||||
SkColorType fColorType;
|
||||
SkAlphaType fAlphaType;
|
||||
};
|
||||
|
||||
#endif
|
@ -14,74 +14,62 @@
|
||||
* instance counting machinery. A class is added to the system by adding:
|
||||
* SK_DECLARE_INST_COUNT at the top of its declaration for derived classes
|
||||
* SK_DECLARE_INST_COUNT_ROOT at the top of its declaration for a root class
|
||||
* SK_DEFINE_INST_COUNT at the top of its .cpp file (for both kinds).
|
||||
* At the end of an application a call to all the "root" objects'
|
||||
* CheckInstanceCount methods should be made
|
||||
*/
|
||||
#include "SkTypes.h"
|
||||
|
||||
#if SK_ENABLE_INST_COUNT
|
||||
// Static variables inside member functions below may be defined multiple times
|
||||
// if Skia is being used as a dynamic library. Instance counting should be on
|
||||
// only for static builds. See bug skia:2058.
|
||||
#if defined(SKIA_DLL)
|
||||
#error Instance counting works only when Skia is built as a static library.
|
||||
#endif
|
||||
|
||||
#include "SkOnce.h"
|
||||
#include "SkTArray.h"
|
||||
#include "SkThread.h"
|
||||
#include "SkThread_platform.h"
|
||||
|
||||
extern bool gPrintInstCount;
|
||||
|
||||
// The non-root classes just register themselves with their parent
|
||||
#define SK_DECLARE_INST_COUNT(className) \
|
||||
SK_DECLARE_INST_COUNT_INTERNAL(className, \
|
||||
INHERITED::AddInstChild(CheckInstanceCount);)
|
||||
INHERITED::AddInstChild(CheckInstanceCount);,\
|
||||
/**/)
|
||||
|
||||
#define SK_DECLARE_INST_COUNT_TEMPLATE(className) \
|
||||
SK_DECLARE_INST_COUNT_INTERNAL(className, \
|
||||
INHERITED::AddInstChild(CheckInstanceCount);, \
|
||||
typename)
|
||||
|
||||
// The root classes registers a function to print out the memory stats when
|
||||
// the app ends
|
||||
#define SK_DECLARE_INST_COUNT_ROOT(className) \
|
||||
SK_DECLARE_INST_COUNT_INTERNAL(className, atexit(exitPrint);)
|
||||
SK_DECLARE_INST_COUNT_INTERNAL(className, atexit(exitPrint);, /**/)
|
||||
|
||||
#define SK_DECLARE_INST_COUNT_INTERNAL(className, initStep) \
|
||||
#define SK_DECLARE_INST_COUNT_INTERNAL(className, initStep, templateType) \
|
||||
class SkInstanceCountHelper { \
|
||||
public: \
|
||||
typedef int (*PFCheckInstCnt)(int level, bool cleanUp); \
|
||||
SkInstanceCountHelper() { \
|
||||
SK_DECLARE_STATIC_ONCE(once); \
|
||||
SkOnce(&once, init, 0); \
|
||||
sk_atomic_inc(GetInstanceCountPtr()); \
|
||||
} \
|
||||
\
|
||||
static void init(int) { \
|
||||
initStep \
|
||||
if (!gInited) { \
|
||||
initStep \
|
||||
gChildren = new SkTArray<PFCheckInstCnt>; \
|
||||
gInited = true; \
|
||||
} \
|
||||
sk_atomic_inc(&gInstanceCount); \
|
||||
} \
|
||||
\
|
||||
SkInstanceCountHelper(const SkInstanceCountHelper&) { \
|
||||
sk_atomic_inc(GetInstanceCountPtr()); \
|
||||
sk_atomic_inc(&gInstanceCount); \
|
||||
} \
|
||||
\
|
||||
~SkInstanceCountHelper() { \
|
||||
sk_atomic_dec(GetInstanceCountPtr()); \
|
||||
} \
|
||||
\
|
||||
static int32_t* GetInstanceCountPtr() { \
|
||||
static int32_t gInstanceCount; \
|
||||
return &gInstanceCount; \
|
||||
} \
|
||||
\
|
||||
static SkTArray<int (*)(int, bool)>*& GetChildren() { \
|
||||
static SkTArray<int (*)(int, bool)>* gChildren; \
|
||||
return gChildren; \
|
||||
} \
|
||||
\
|
||||
static SkBaseMutex& GetChildrenMutex() { \
|
||||
SK_DECLARE_STATIC_MUTEX(childrenMutex); \
|
||||
return childrenMutex; \
|
||||
sk_atomic_dec(&gInstanceCount); \
|
||||
} \
|
||||
\
|
||||
static int32_t gInstanceCount; \
|
||||
static bool gInited; \
|
||||
static SkTArray<PFCheckInstCnt>* gChildren; \
|
||||
} fInstanceCountHelper; \
|
||||
\
|
||||
static int32_t GetInstanceCount() { \
|
||||
return *SkInstanceCountHelper::GetInstanceCountPtr(); \
|
||||
return SkInstanceCountHelper::gInstanceCount; \
|
||||
} \
|
||||
\
|
||||
static void exitPrint() { \
|
||||
@ -89,54 +77,57 @@ extern bool gPrintInstCount;
|
||||
} \
|
||||
\
|
||||
static int CheckInstanceCount(int level = 0, bool cleanUp = false) { \
|
||||
if (gPrintInstCount && 0 != GetInstanceCount()) { \
|
||||
if (gPrintInstCount && 0 != SkInstanceCountHelper::gInstanceCount) {\
|
||||
SkDebugf("%*c Leaked %s: %d\n", \
|
||||
4*level, ' ', #className, \
|
||||
GetInstanceCount()); \
|
||||
SkInstanceCountHelper::gInstanceCount); \
|
||||
} \
|
||||
if (NULL == SkInstanceCountHelper::GetChildren()) { \
|
||||
return GetInstanceCount(); \
|
||||
if (NULL == SkInstanceCountHelper::gChildren) { \
|
||||
return SkInstanceCountHelper::gInstanceCount; \
|
||||
} \
|
||||
SkTArray<int (*)(int, bool)>* children = \
|
||||
SkInstanceCountHelper::GetChildren(); \
|
||||
int childCount = children->count(); \
|
||||
int count = GetInstanceCount(); \
|
||||
int childCount = SkInstanceCountHelper::gChildren->count(); \
|
||||
int count = SkInstanceCountHelper::gInstanceCount; \
|
||||
for (int i = 0; i < childCount; ++i) { \
|
||||
count -= (*(*children)[i])(level+1, cleanUp); \
|
||||
count -= (*(*SkInstanceCountHelper::gChildren)[i])(level+1, cleanUp); \
|
||||
} \
|
||||
SkASSERT(count >= 0); \
|
||||
if (gPrintInstCount && childCount > 0 && count > 0) { \
|
||||
SkDebugf("%*c Leaked ???: %d\n", 4*(level + 1), ' ', count); \
|
||||
} \
|
||||
if (cleanUp) { \
|
||||
delete children; \
|
||||
SkInstanceCountHelper::GetChildren() = NULL; \
|
||||
delete SkInstanceCountHelper::gChildren; \
|
||||
SkInstanceCountHelper::gChildren = NULL; \
|
||||
} \
|
||||
return GetInstanceCount(); \
|
||||
return SkInstanceCountHelper::gInstanceCount; \
|
||||
} \
|
||||
\
|
||||
static void AddInstChild(int (*childCheckInstCnt)(int, bool)) { \
|
||||
if (CheckInstanceCount != childCheckInstCnt) { \
|
||||
SkAutoMutexAcquire ama(SkInstanceCountHelper::GetChildrenMutex()); \
|
||||
if (NULL == SkInstanceCountHelper::GetChildren()) { \
|
||||
SkInstanceCountHelper::GetChildren() = \
|
||||
new SkTArray<int (*)(int, bool)>; \
|
||||
} \
|
||||
SkInstanceCountHelper::GetChildren()->push_back(childCheckInstCnt); \
|
||||
static void AddInstChild(templateType SkInstanceCountHelper::PFCheckInstCnt \
|
||||
childCheckInstCnt) { \
|
||||
if (CheckInstanceCount != childCheckInstCnt && \
|
||||
NULL != SkInstanceCountHelper::gChildren) { \
|
||||
SkInstanceCountHelper::gChildren->push_back(childCheckInstCnt); \
|
||||
} \
|
||||
}
|
||||
|
||||
#else
|
||||
// Typically SK_ENABLE_INST_COUNT=0. Make sure the class declares public typedef INHERITED by
|
||||
// causing a compile-time error if the typedef is missing. This way SK_ENABLE_INST_COUNT=1 stays
|
||||
// compiling.
|
||||
#define SK_DECLARE_INST_COUNT(className) static void AddInstChild() { INHERITED::AddInstChild(); }
|
||||
#define SK_DECLARE_INST_COUNT_ROOT(className) static void AddInstChild() { }
|
||||
#endif
|
||||
#define SK_DEFINE_INST_COUNT(className) \
|
||||
int32_t className::SkInstanceCountHelper::gInstanceCount = 0; \
|
||||
bool className::SkInstanceCountHelper::gInited = false; \
|
||||
SkTArray<className::SkInstanceCountHelper::PFCheckInstCnt>* \
|
||||
className::SkInstanceCountHelper::gChildren = NULL;
|
||||
|
||||
// Following are deprecated. They are defined only for backwards API compatibility.
|
||||
#define SK_DECLARE_INST_COUNT_TEMPLATE(className) SK_DECLARE_INST_COUNT(className)
|
||||
#define SK_DEFINE_INST_COUNT_TEMPLATE(templateInfo, className) \
|
||||
templateInfo int32_t className::SkInstanceCountHelper::gInstanceCount = 0;\
|
||||
templateInfo bool className::SkInstanceCountHelper::gInited = false; \
|
||||
templateInfo \
|
||||
SkTArray<typename className::SkInstanceCountHelper::PFCheckInstCnt>*\
|
||||
className::SkInstanceCountHelper::gChildren = NULL;
|
||||
|
||||
#else
|
||||
#define SK_DECLARE_INST_COUNT(className)
|
||||
#define SK_DECLARE_INST_COUNT_TEMPLATE(className)
|
||||
#define SK_DECLARE_INST_COUNT_ROOT(className)
|
||||
#define SK_DEFINE_INST_COUNT(className)
|
||||
#define SK_DEFINE_INST_COUNT_TEMPLATE(templateInfo, className)
|
||||
#endif
|
||||
|
||||
#endif // SkInstCnt_DEFINED
|
51
gfx/skia/include/core/SkMallocPixelRef.h
Normal file
51
gfx/skia/include/core/SkMallocPixelRef.h
Normal file
@ -0,0 +1,51 @@
|
||||
|
||||
/*
|
||||
* 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 "SkPixelRef.h"
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
class SkMallocPixelRef : public SkPixelRef {
|
||||
public:
|
||||
/** Allocate the specified buffer for pixels. The memory is freed when the
|
||||
last owner of this pixelref is gone. If addr is NULL, sk_malloc_throw()
|
||||
is called to allocate it.
|
||||
*/
|
||||
SkMallocPixelRef(void* addr, size_t size, SkColorTable* ctable, bool ownPixels = true);
|
||||
virtual ~SkMallocPixelRef();
|
||||
|
||||
//! Return the allocation size for the pixels
|
||||
size_t getSize() const { return fSize; }
|
||||
void* getAddr() const { return fStorage; }
|
||||
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMallocPixelRef)
|
||||
|
||||
protected:
|
||||
// overrides from SkPixelRef
|
||||
virtual void* onLockPixels(SkColorTable**);
|
||||
virtual void onUnlockPixels();
|
||||
|
||||
SkMallocPixelRef(SkFlattenableReadBuffer& buffer);
|
||||
virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
void* fStorage;
|
||||
size_t fSize;
|
||||
SkColorTable* fCTable;
|
||||
bool fOwnPixels;
|
||||
|
||||
typedef SkPixelRef INHERITED;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
@ -99,19 +99,6 @@ struct SkMask {
|
||||
return row + (x - fBounds.fLeft);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the address of the specified 32bit mask. In the debug build,
|
||||
* this asserts that the mask's format is 32bits, and that (x,y)
|
||||
* are contained in the mask's fBounds.
|
||||
*/
|
||||
uint32_t* getAddr32(int x, int y) const {
|
||||
SkASSERT(kLCD32_Format == fFormat || kARGB32_Format == fFormat);
|
||||
SkASSERT(fBounds.contains(x, y));
|
||||
SkASSERT(fImage != NULL);
|
||||
uint32_t* row = (uint32_t*)(fImage + (y - fBounds.fTop) * fRowBytes);
|
||||
return row + (x - fBounds.fLeft);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the address of the specified pixel, computing the pixel-size
|
||||
* at runtime based on the mask format. This will be slightly slower than
|
||||
@ -157,6 +144,5 @@ public:
|
||||
private:
|
||||
uint8_t* fImage;
|
||||
};
|
||||
#define SkAutoMaskFreeImage(...) SK_REQUIRE_LOCAL_VAR(SkAutoMaskFreeImage)
|
||||
|
||||
#endif
|
@ -14,16 +14,11 @@
|
||||
#include "SkMask.h"
|
||||
#include "SkPaint.h"
|
||||
|
||||
class GrContext;
|
||||
class GrPaint;
|
||||
class SkBitmap;
|
||||
class SkBlitter;
|
||||
class SkBounder;
|
||||
class SkMatrix;
|
||||
class SkPath;
|
||||
class SkRasterClip;
|
||||
class SkRRect;
|
||||
class SkStrokeRec;
|
||||
|
||||
/** \class SkMaskFilter
|
||||
|
||||
@ -63,61 +58,27 @@ public:
|
||||
virtual bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&,
|
||||
SkIPoint* margin) const;
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
/**
|
||||
* Returns true if the filter can be expressed a single-pass GrEffect without requiring an
|
||||
* explicit input mask. Per-pixel, the effect receives the incoming mask's coverage as
|
||||
* the input color and outputs the filtered covereage value. This means that each pixel's
|
||||
* filtered coverage must only depend on the unfiltered mask value for that pixel and not on
|
||||
* surrounding values.
|
||||
*
|
||||
* If effect is non-NULL, a new GrEffect instance is stored in it. The caller assumes ownership
|
||||
* of the effect and must unref it.
|
||||
*/
|
||||
virtual bool asNewEffect(GrEffectRef** effect,
|
||||
GrTexture*,
|
||||
const SkMatrix& ctm) const;
|
||||
enum BlurType {
|
||||
kNone_BlurType, //!< this maskfilter is not a blur
|
||||
kNormal_BlurType, //!< fuzzy inside and outside
|
||||
kSolid_BlurType, //!< solid inside, fuzzy outside
|
||||
kOuter_BlurType, //!< nothing inside, fuzzy outside
|
||||
kInner_BlurType //!< fuzzy inside, nothing outside
|
||||
};
|
||||
|
||||
struct BlurInfo {
|
||||
SkScalar fRadius;
|
||||
bool fIgnoreTransform;
|
||||
bool fHighQuality;
|
||||
};
|
||||
|
||||
/**
|
||||
* If asNewEffect() fails the filter may be implemented on the GPU by a subclass overriding
|
||||
* filterMaskGPU (declared below). That code path requires constructing a src mask as input.
|
||||
* Since that is a potentially expensive operation, the subclass must also override this
|
||||
* function to indicate whether filterTextureMaskGPU would succeeed if the mask were to be
|
||||
* created.
|
||||
*
|
||||
* 'maskRect' returns the device space portion of the mask that the filter needs. The mask
|
||||
* passed into 'filterMaskGPU' should have the same extent as 'maskRect' but be translated
|
||||
* to the upper-left corner of the mask (i.e., (maskRect.fLeft, maskRect.fTop) appears at
|
||||
* (0, 0) in the mask).
|
||||
* Optional method for maskfilters that can be described as a blur. If so,
|
||||
* they return the corresponding BlurType and set the fields in BlurInfo
|
||||
* (if not null). If they cannot be described as a blur, they return
|
||||
* kNone_BlurType and ignore the info parameter.
|
||||
*/
|
||||
virtual bool canFilterMaskGPU(const SkRect& devBounds,
|
||||
const SkIRect& clipBounds,
|
||||
const SkMatrix& ctm,
|
||||
SkRect* maskRect) const;
|
||||
|
||||
/**
|
||||
* Try to directly render the mask filter into the target. Returns
|
||||
* true if drawing was successful.
|
||||
*/
|
||||
virtual bool directFilterMaskGPU(GrContext* context,
|
||||
GrPaint* grp,
|
||||
const SkStrokeRec& strokeRec,
|
||||
const SkPath& path) const;
|
||||
|
||||
/**
|
||||
* This function is used to implement filters that require an explicit src mask. It should only
|
||||
* be called if canFilterMaskGPU returned true and the maskRect param should be the output from
|
||||
* that call. canOverwriteSrc indicates whether the implementation may treat src as a scratch
|
||||
* texture and overwrite its contents. When true it is also legal to return src as the result.
|
||||
* Implementations are free to get the GrContext from the src texture in order to create
|
||||
* additional textures and perform multiple passes.
|
||||
*/
|
||||
virtual bool filterMaskGPU(GrTexture* src,
|
||||
const SkMatrix& ctm,
|
||||
const SkRect& maskRect,
|
||||
GrTexture** result,
|
||||
bool canOverwriteSrc) const;
|
||||
#endif
|
||||
virtual BlurType asABlur(BlurInfo*) const;
|
||||
|
||||
/**
|
||||
* The fast bounds function is used to enable the paint to be culled early
|
||||
@ -133,11 +94,10 @@ public:
|
||||
virtual void computeFastBounds(const SkRect& src, SkRect* dest) const;
|
||||
|
||||
SkDEVCODE(virtual void toString(SkString* str) const = 0;)
|
||||
SK_DEFINE_FLATTENABLE_TYPE(SkMaskFilter)
|
||||
|
||||
protected:
|
||||
// empty for now, but lets get our subclass to remember to init us for the future
|
||||
SkMaskFilter(SkReadBuffer& buffer) : INHERITED(buffer) {}
|
||||
SkMaskFilter(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
|
||||
|
||||
enum FilterReturn {
|
||||
kFalse_FilterReturn,
|
||||
@ -170,12 +130,6 @@ protected:
|
||||
const SkMatrix&,
|
||||
const SkIRect& clipBounds,
|
||||
NinePatch*) const;
|
||||
/**
|
||||
* Similar to filterRectsToNine, except it performs the work on a round rect.
|
||||
*/
|
||||
virtual FilterReturn filterRRectToNine(const SkRRect&, const SkMatrix&,
|
||||
const SkIRect& clipBounds,
|
||||
NinePatch*) const;
|
||||
|
||||
private:
|
||||
friend class SkDraw;
|
||||
@ -189,14 +143,6 @@ private:
|
||||
const SkRasterClip&, SkBounder*, SkBlitter* blitter,
|
||||
SkPaint::Style style) const;
|
||||
|
||||
/** Helper method that, given a roundRect in device space, will rasterize it into a kA8_Format
|
||||
mask and then call filterMask(). If this returns true, the specified blitter will be called
|
||||
to render that mask. Returns false if filterMask() returned false.
|
||||
*/
|
||||
bool filterRRect(const SkRRect& devRRect, const SkMatrix& devMatrix,
|
||||
const SkRasterClip&, SkBounder*, SkBlitter* blitter,
|
||||
SkPaint::Style style) const;
|
||||
|
||||
typedef SkFlattenable INHERITED;
|
||||
};
|
||||
|
@ -35,58 +35,17 @@ int32_t SkSqrtBits(int32_t value, int bitBias);
|
||||
*/
|
||||
#define SkSqrt32(n) SkSqrtBits(n, 15)
|
||||
|
||||
// 64bit -> 32bit utilities
|
||||
|
||||
/**
|
||||
* Return true iff the 64bit value can exactly be represented in signed 32bits
|
||||
*/
|
||||
static inline bool sk_64_isS32(int64_t value) {
|
||||
return (int32_t)value == value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the 64bit argument as signed 32bits, asserting in debug that the arg
|
||||
* exactly fits in signed 32bits. In the release build, no checks are preformed
|
||||
* and the return value if the arg does not fit is undefined.
|
||||
*/
|
||||
static inline int32_t sk_64_asS32(int64_t value) {
|
||||
SkASSERT(sk_64_isS32(value));
|
||||
return (int32_t)value;
|
||||
}
|
||||
|
||||
// Handy util that can be passed two ints, and will automatically promote to
|
||||
// 64bits before the multiply, so the caller doesn't have to remember to cast
|
||||
// e.g. (int64_t)a * b;
|
||||
static inline int64_t sk_64_mul(int64_t a, int64_t b) {
|
||||
return a * b;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//! Returns the number of leading zero bits (0...32)
|
||||
int SkCLZ_portable(uint32_t);
|
||||
|
||||
#ifndef SkCLZ
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
#include <intrin.h>
|
||||
#if defined(SK_CPU_ARM)
|
||||
#define SkCLZ(x) __builtin_clz(x)
|
||||
#endif
|
||||
|
||||
static inline int SkCLZ(uint32_t mask) {
|
||||
if (mask) {
|
||||
DWORD index;
|
||||
_BitScanReverse(&index, mask);
|
||||
return index ^ 0x1F;
|
||||
} else {
|
||||
return 32;
|
||||
}
|
||||
}
|
||||
#elif defined(SK_CPU_ARM) || defined(__GNUC__) || defined(__clang__)
|
||||
static inline int SkCLZ(uint32_t mask) {
|
||||
// __builtin_clz(0) is undefined, so we have to detect that case.
|
||||
return mask ? __builtin_clz(mask) : 32;
|
||||
}
|
||||
#else
|
||||
#define SkCLZ(x) SkCLZ_portable(x)
|
||||
#endif
|
||||
#ifndef SkCLZ
|
||||
#define SkCLZ(x) SkCLZ_portable(x)
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -180,7 +139,7 @@ static inline bool SkIsPow2(int value) {
|
||||
* Return a*b/((1 << shift) - 1), rounding any fractional bits.
|
||||
* Only valid if a and b are unsigned and <= 32767 and shift is > 0 and <= 8
|
||||
*/
|
||||
static inline unsigned SkMul16ShiftRound(U16CPU a, U16CPU b, int shift) {
|
||||
static inline unsigned SkMul16ShiftRound(unsigned a, unsigned b, int shift) {
|
||||
SkASSERT(a <= 32767);
|
||||
SkASSERT(b <= 32767);
|
||||
SkASSERT(shift > 0 && shift <= 8);
|
||||
@ -189,36 +148,14 @@ static inline unsigned SkMul16ShiftRound(U16CPU a, U16CPU b, int shift) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a*b/255, rounding any fractional bits.
|
||||
* Only valid if a and b are unsigned and <= 32767.
|
||||
* Return a*b/255, rounding any fractional bits. Only valid if both
|
||||
* a and b are 0..255
|
||||
*/
|
||||
static inline U8CPU SkMulDiv255Round(U16CPU a, U16CPU b) {
|
||||
SkASSERT(a <= 32767);
|
||||
SkASSERT(b <= 32767);
|
||||
static inline U8CPU SkMulDiv255Round(U8CPU a, U8CPU b) {
|
||||
SkASSERT((uint8_t)a == a);
|
||||
SkASSERT((uint8_t)b == b);
|
||||
unsigned prod = SkMulS16(a, b) + 128;
|
||||
return (prod + (prod >> 8)) >> 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores numer/denom and numer%denom into div and mod respectively.
|
||||
*/
|
||||
template <typename In, typename Out>
|
||||
inline void SkTDivMod(In numer, In denom, Out* div, Out* mod) {
|
||||
#ifdef SK_CPU_ARM
|
||||
// If we wrote this as in the else branch, GCC won't fuse the two into one
|
||||
// divmod call, but rather a div call followed by a divmod. Silly! This
|
||||
// version is just as fast as calling __aeabi_[u]idivmod manually, but with
|
||||
// prettier code.
|
||||
//
|
||||
// This benches as around 2x faster than the code in the else branch.
|
||||
const In d = numer/denom;
|
||||
*div = static_cast<Out>(d);
|
||||
*mod = static_cast<Out>(numer-d*denom);
|
||||
#else
|
||||
// On x86 this will just be a single idiv.
|
||||
*div = static_cast<Out>(numer/denom);
|
||||
*mod = static_cast<Out>(numer%denom);
|
||||
#endif // SK_CPU_ARM
|
||||
}
|
||||
|
||||
#endif
|
@ -14,10 +14,15 @@
|
||||
|
||||
class SkString;
|
||||
|
||||
// TODO: can we remove these 3 (need to check chrome/android)
|
||||
typedef SkScalar SkPersp;
|
||||
#define SkScalarToPersp(x) (x)
|
||||
#define SkPerspToScalar(x) (x)
|
||||
#ifdef SK_SCALAR_IS_FLOAT
|
||||
typedef SkScalar SkPersp;
|
||||
#define SkScalarToPersp(x) (x)
|
||||
#define SkPerspToScalar(x) (x)
|
||||
#else
|
||||
typedef SkFract SkPersp;
|
||||
#define SkScalarToPersp(x) SkFixedToFract(x)
|
||||
#define SkPerspToScalar(x) SkFractToFixed(x)
|
||||
#endif
|
||||
|
||||
/** \class SkMatrix
|
||||
|
||||
@ -85,12 +90,6 @@ public:
|
||||
*/
|
||||
bool isSimilarity(SkScalar tol = SK_ScalarNearlyZero) const;
|
||||
|
||||
/** Returns true if the matrix contains only translation, rotation or scale
|
||||
(non-uniform scale is allowed).
|
||||
Returns false if other transformation types are included or is degenerate
|
||||
*/
|
||||
bool preservesRightAngles(SkScalar tol = SK_ScalarNearlyZero) const;
|
||||
|
||||
enum {
|
||||
kMScaleX,
|
||||
kMSkewX,
|
||||
@ -418,19 +417,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/** Apply this matrix to the array of homogeneous points, specified by src,
|
||||
where a homogeneous point is defined by 3 contiguous scalar values,
|
||||
and write the transformed points into the array of scalars specified by dst.
|
||||
dst[] = M * src[]
|
||||
@param dst Where the transformed coordinates are written. It must
|
||||
contain at least 3 * count entries
|
||||
@param src The original coordinates that are to be transformed. It
|
||||
must contain at least 3 * count entries
|
||||
@param count The number of triples (homogeneous points) in src to read,
|
||||
and then transform into dst.
|
||||
*/
|
||||
void mapHomogeneousPoints(SkScalar dst[], const SkScalar src[], int count) const;
|
||||
|
||||
void mapXY(SkScalar x, SkScalar y, SkPoint* result) const {
|
||||
SkASSERT(result);
|
||||
this->getMapXYProc()(*this, x, y, result);
|
||||
@ -478,18 +464,6 @@ public:
|
||||
return this->mapRect(rect, *rect);
|
||||
}
|
||||
|
||||
/** Apply this matrix to the src rectangle, and write the four transformed
|
||||
points into dst. The points written to dst will be the original top-left, top-right,
|
||||
bottom-right, and bottom-left points transformed by the matrix.
|
||||
@param dst Where the transformed quad is written.
|
||||
@param rect The original rectangle to be transformed.
|
||||
*/
|
||||
void mapRectToQuad(SkPoint dst[4], const SkRect& rect) const {
|
||||
// This could potentially be faster if we only transformed each x and y of the rect once.
|
||||
rect.toQuad(dst);
|
||||
this->mapPoints(dst, 4);
|
||||
}
|
||||
|
||||
/** Return the mean radius of a circle after it has been mapped by
|
||||
this matrix. NOTE: in perspective this value assumes the circle
|
||||
has its center at the origin.
|
||||
@ -538,7 +512,13 @@ public:
|
||||
return 0 == memcmp(fMat, m.fMat, sizeof(fMat));
|
||||
}
|
||||
|
||||
#ifdef SK_SCALAR_IS_FIXED
|
||||
friend bool operator==(const SkMatrix& a, const SkMatrix& b) {
|
||||
return a.cheapEqualTo(b);
|
||||
}
|
||||
#else
|
||||
friend bool operator==(const SkMatrix& a, const SkMatrix& b);
|
||||
#endif
|
||||
friend bool operator!=(const SkMatrix& a, const SkMatrix& b) {
|
||||
return !(a == b);
|
||||
}
|
||||
@ -548,28 +528,13 @@ public:
|
||||
kMaxFlattenSize = 9 * sizeof(SkScalar) + sizeof(uint32_t)
|
||||
};
|
||||
// return the number of bytes written, whether or not buffer is null
|
||||
size_t writeToMemory(void* buffer) const;
|
||||
/**
|
||||
* Reads data from the buffer parameter
|
||||
*
|
||||
* @param buffer Memory to read from
|
||||
* @param length Amount of memory available in the buffer
|
||||
* @return number of bytes read (must be a multiple of 4) or
|
||||
* 0 if there was not enough memory available
|
||||
*/
|
||||
size_t readFromMemory(const void* buffer, size_t length);
|
||||
uint32_t writeToMemory(void* buffer) const;
|
||||
// return the number of bytes read
|
||||
uint32_t readFromMemory(const void* buffer);
|
||||
|
||||
SkDEVCODE(void dump() const;)
|
||||
SkDEVCODE(void toString(SkString*) const;)
|
||||
|
||||
/**
|
||||
* Calculates the minimum stretching factor of the matrix. If the matrix has
|
||||
* perspective -1 is returned.
|
||||
*
|
||||
* @return minumum strecthing factor
|
||||
*/
|
||||
SkScalar getMinStretch() const;
|
||||
|
||||
/**
|
||||
* Calculates the maximum stretching factor of the matrix. If the matrix has
|
||||
* perspective -1 is returned.
|
@ -48,35 +48,9 @@ char* sk_fgets(char* str, int size, SkFILE* f);
|
||||
|
||||
void sk_fflush(SkFILE*);
|
||||
|
||||
bool sk_fseek(SkFILE*, size_t);
|
||||
bool sk_fmove(SkFILE*, long);
|
||||
int sk_fseek(SkFILE*, size_t, int);
|
||||
size_t sk_ftell(SkFILE*);
|
||||
|
||||
/** Maps a file into memory. Returns the address and length on success, NULL otherwise.
|
||||
* The mapping is read only.
|
||||
* When finished with the mapping, free the returned pointer with sk_fmunmap.
|
||||
*/
|
||||
void* sk_fmmap(SkFILE* f, size_t* length);
|
||||
|
||||
/** Maps a file descriptor into memory. Returns the address and length on success, NULL otherwise.
|
||||
* The mapping is read only.
|
||||
* When finished with the mapping, free the returned pointer with sk_fmunmap.
|
||||
*/
|
||||
void* sk_fdmmap(int fd, size_t* length);
|
||||
|
||||
/** Unmaps a file previously mapped by sk_fmmap or sk_fdmmap.
|
||||
* The length parameter must be the same as returned from sk_fmmap.
|
||||
*/
|
||||
void sk_fmunmap(const void* addr, size_t length);
|
||||
|
||||
/** Returns true if the two point at the exact same filesystem object. */
|
||||
bool sk_fidentical(SkFILE* a, SkFILE* b);
|
||||
|
||||
/** Returns the underlying file descriptor for the given file.
|
||||
* The return value will be < 0 on failure.
|
||||
*/
|
||||
int sk_fileno(SkFILE* f);
|
||||
|
||||
// Returns true if something (file, directory, ???) exists at this path.
|
||||
bool sk_exists(const char *path);
|
||||
|
||||
@ -131,29 +105,4 @@ private:
|
||||
uint16_t* fStr;
|
||||
};
|
||||
|
||||
/**
|
||||
* Functions for modifying SkStrings which represent paths on the filesystem.
|
||||
*/
|
||||
class SkOSPath {
|
||||
public:
|
||||
/**
|
||||
* Assembles rootPath and relativePath into a single path, like this:
|
||||
* rootPath/relativePath.
|
||||
* It is okay to call with a NULL rootPath and/or relativePath. A path
|
||||
* separator will still be inserted.
|
||||
*
|
||||
* Uses SkPATH_SEPARATOR, to work on all platforms.
|
||||
*/
|
||||
static SkString SkPathJoin(const char *rootPath, const char *relativePath);
|
||||
|
||||
/**
|
||||
* Return the name of the file, ignoring the directory structure.
|
||||
* Behaves like python's os.path.basename. If the fullPath is
|
||||
* /dir/subdir/, an empty string is returned.
|
||||
* @param fullPath Full path to the file.
|
||||
* @return SkString The basename of the file - anything beyond the
|
||||
* final slash, or the full name if there is no slash.
|
||||
*/
|
||||
static SkString SkBasename(const char* fullPath);
|
||||
};
|
||||
#endif
|
@ -13,24 +13,21 @@
|
||||
|
||||
#include "SkColor.h"
|
||||
#include "SkDrawLooper.h"
|
||||
#include "SkMatrix.h"
|
||||
#include "SkXfermode.h"
|
||||
#ifdef SK_BUILD_FOR_ANDROID
|
||||
#include "SkPaintOptionsAndroid.h"
|
||||
#endif
|
||||
|
||||
class SkAnnotation;
|
||||
class SkAutoGlyphCache;
|
||||
class SkColorFilter;
|
||||
class SkDescriptor;
|
||||
struct SkDeviceProperties;
|
||||
class SkReadBuffer;
|
||||
class SkWriteBuffer;
|
||||
class SkFlattenableReadBuffer;
|
||||
class SkFlattenableWriteBuffer;
|
||||
struct SkGlyph;
|
||||
struct SkRect;
|
||||
class SkGlyphCache;
|
||||
class SkImageFilter;
|
||||
class SkMaskFilter;
|
||||
class SkMatrix;
|
||||
class SkPath;
|
||||
class SkPathEffect;
|
||||
struct SkPoint;
|
||||
@ -43,23 +40,12 @@ typedef const SkGlyph& (*SkDrawCacheProc)(SkGlyphCache*, const char**,
|
||||
|
||||
typedef const SkGlyph& (*SkMeasureCacheProc)(SkGlyphCache*, const char**);
|
||||
|
||||
#define kBicubicFilterBitmap_Flag kHighQualityFilterBitmap_Flag
|
||||
|
||||
/** \class SkPaint
|
||||
|
||||
The SkPaint class holds the style and color information about how to draw
|
||||
geometries, text and bitmaps.
|
||||
*/
|
||||
|
||||
class SK_API SkPaint {
|
||||
enum {
|
||||
// DEPRECATED -- use setFilterLevel instead
|
||||
kFilterBitmap_Flag = 0x02, // temporary flag
|
||||
// DEPRECATED -- use setFilterLevel instead
|
||||
kHighQualityFilterBitmap_Flag = 0x4000, // temporary flag
|
||||
// DEPRECATED -- use setFilterLevel instead
|
||||
kHighQualityDownsampleBitmap_Flag = 0x8000, // temporary flag
|
||||
};
|
||||
public:
|
||||
SkPaint();
|
||||
SkPaint(const SkPaint& paint);
|
||||
@ -72,8 +58,8 @@ public:
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
void flatten(SkWriteBuffer&) const;
|
||||
void unflatten(SkReadBuffer&);
|
||||
void flatten(SkFlattenableWriteBuffer&) const;
|
||||
void unflatten(SkFlattenableReadBuffer&);
|
||||
|
||||
/** Restores the paint to its initial settings.
|
||||
*/
|
||||
@ -106,6 +92,7 @@ public:
|
||||
*/
|
||||
enum Flags {
|
||||
kAntiAlias_Flag = 0x01, //!< mask to enable antialiasing
|
||||
kFilterBitmap_Flag = 0x02, //!< mask to enable bitmap filtering
|
||||
kDither_Flag = 0x04, //!< mask to enable dithering
|
||||
kUnderlineText_Flag = 0x08, //!< mask to enable underline text
|
||||
kStrikeThruText_Flag = 0x10, //!< mask to enable strike-thru text
|
||||
@ -118,10 +105,11 @@ public:
|
||||
kAutoHinting_Flag = 0x800, //!< mask to force Freetype's autohinter
|
||||
kVerticalText_Flag = 0x1000,
|
||||
kGenA8FromLCD_Flag = 0x2000, // hack for GDI -- do not use if you can help it
|
||||
|
||||
// when adding extra flags, note that the fFlags member is specified
|
||||
// with a bit-width and you'll have to expand it.
|
||||
|
||||
kAllFlags = 0xFFFF
|
||||
kAllFlags = 0x3FFF
|
||||
};
|
||||
|
||||
/** Return the paint's flags. Use the Flag enum to test flag values.
|
||||
@ -284,42 +272,12 @@ public:
|
||||
*/
|
||||
void setDevKernText(bool devKernText);
|
||||
|
||||
enum FilterLevel {
|
||||
kNone_FilterLevel,
|
||||
kLow_FilterLevel,
|
||||
kMedium_FilterLevel,
|
||||
kHigh_FilterLevel
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the filter level. This affects the quality (and performance) of
|
||||
* drawing scaled images.
|
||||
*/
|
||||
FilterLevel getFilterLevel() const;
|
||||
|
||||
/**
|
||||
* Set the filter level. This affects the quality (and performance) of
|
||||
* drawing scaled images.
|
||||
*/
|
||||
void setFilterLevel(FilterLevel);
|
||||
|
||||
/**
|
||||
* If the predicate is true, set the filterLevel to Low, else set it to
|
||||
* None.
|
||||
*/
|
||||
SK_ATTR_DEPRECATED("use setFilterLevel")
|
||||
void setFilterBitmap(bool doFilter) {
|
||||
this->setFilterLevel(doFilter ? kLow_FilterLevel : kNone_FilterLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if getFilterLevel() returns anything other than None.
|
||||
*/
|
||||
SK_ATTR_DEPRECATED("use getFilterLevel")
|
||||
bool isFilterBitmap() const {
|
||||
return kNone_FilterLevel != this->getFilterLevel();
|
||||
return SkToBool(this->getFlags() & kFilterBitmap_Flag);
|
||||
}
|
||||
|
||||
void setFilterBitmap(bool filterBitmap);
|
||||
|
||||
/** Styles apply to rect, oval, path, and text.
|
||||
Bitmaps are always drawn in "fill", and lines are always drawn in
|
||||
"stroke".
|
||||
@ -639,8 +597,9 @@ public:
|
||||
* Returns true if there is an annotation installed on this paint, and
|
||||
* the annotation specifics no-drawing.
|
||||
*/
|
||||
SK_ATTR_DEPRECATED("use getAnnotation and check for non-null")
|
||||
bool isNoDrawAnnotation() const { return this->getAnnotation() != NULL; }
|
||||
bool isNoDrawAnnotation() const {
|
||||
return SkToBool(fPrivFlags & kNoDrawAnnotation_PrivFlag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the paint's SkDrawLooper (if any). Does not affect the looper's
|
||||
@ -665,9 +624,8 @@ public:
|
||||
kLeft_Align,
|
||||
kCenter_Align,
|
||||
kRight_Align,
|
||||
};
|
||||
enum {
|
||||
kAlignCount = 3
|
||||
|
||||
kAlignCount
|
||||
};
|
||||
|
||||
/** Return the paint's Align value for drawing text.
|
||||
@ -716,6 +674,20 @@ public:
|
||||
*/
|
||||
void setTextSkewX(SkScalar skewX);
|
||||
|
||||
#ifdef SK_SUPPORT_HINTING_SCALE_FACTOR
|
||||
/** Return the paint's scale factor used for correctly rendering
|
||||
glyphs in high DPI mode without text subpixel positioning.
|
||||
@return the scale factor used for rendering glyphs in high DPI mode.
|
||||
*/
|
||||
SkScalar getHintingScaleFactor() const { return fHintingScaleFactor; }
|
||||
|
||||
/** Set the paint's scale factor used for correctly rendering
|
||||
glyphs in high DPI mode without text subpixel positioning.
|
||||
@param the scale factor used for rendering glyphs in high DPI mode.
|
||||
*/
|
||||
void setHintingScaleFactor(SkScalar hintingScaleFactor);
|
||||
#endif
|
||||
|
||||
/** Describes how to interpret the text parameters that are passed to paint
|
||||
methods like measureText() and getTextWidths().
|
||||
*/
|
||||
@ -737,11 +709,9 @@ public:
|
||||
SkScalar fBottom; //!< The greatest distance below the baseline for any glyph (will be >= 0)
|
||||
SkScalar fLeading; //!< The recommended distance to add between lines of text (will be >= 0)
|
||||
SkScalar fAvgCharWidth; //!< the average charactor width (>= 0)
|
||||
SkScalar fMaxCharWidth; //!< the max charactor width (>= 0)
|
||||
SkScalar fXMin; //!< The minimum bounding box x value for all glyphs
|
||||
SkScalar fXMax; //!< The maximum bounding box x value for all glyphs
|
||||
SkScalar fXHeight; //!< The height of an 'x' in px, or 0 if no 'x' in face
|
||||
SkScalar fCapHeight; //!< The cap height (> 0), or 0 if cannot be determined.
|
||||
SkScalar fXHeight; //!< the height of an 'x' in px, or 0 if no 'x' in face
|
||||
};
|
||||
|
||||
/** Return the recommend spacing between lines (which will be
|
||||
@ -890,11 +860,6 @@ public:
|
||||
/** Returns the base glyph count for the strike associated with this paint
|
||||
*/
|
||||
unsigned getBaseGlyphCount(SkUnichar text) const;
|
||||
|
||||
const SkPaintOptionsAndroid& getPaintOptionsAndroid() const {
|
||||
return fPaintOptionsAndroid;
|
||||
}
|
||||
void setPaintOptionsAndroid(const SkPaintOptionsAndroid& options);
|
||||
#endif
|
||||
|
||||
// returns true if the paint's settings (e.g. xfermode + alpha) resolve to
|
||||
@ -943,7 +908,6 @@ public:
|
||||
uintptr_t effects = reinterpret_cast<uintptr_t>(this->getLooper());
|
||||
effects |= reinterpret_cast<uintptr_t>(this->getMaskFilter());
|
||||
effects |= reinterpret_cast<uintptr_t>(this->getPathEffect());
|
||||
effects |= reinterpret_cast<uintptr_t>(this->getImageFilter());
|
||||
if (!effects) {
|
||||
return orig;
|
||||
}
|
||||
@ -962,22 +926,6 @@ public:
|
||||
const SkRect& doComputeFastBounds(const SkRect& orig, SkRect* storage,
|
||||
Style) const;
|
||||
|
||||
/**
|
||||
* Return a matrix that applies the paint's text values: size, scale, skew
|
||||
*/
|
||||
static SkMatrix* SetTextMatrix(SkMatrix* matrix, SkScalar size,
|
||||
SkScalar scaleX, SkScalar skewX) {
|
||||
matrix->setScale(size * scaleX, size);
|
||||
if (skewX) {
|
||||
matrix->postSkew(skewX, 0);
|
||||
}
|
||||
return matrix;
|
||||
}
|
||||
|
||||
SkMatrix* setTextMatrix(SkMatrix* matrix) const {
|
||||
return SetTextMatrix(matrix, fTextSize, fTextScaleX, fTextSkewX);
|
||||
}
|
||||
|
||||
SkDEVCODE(void toString(SkString*) const;)
|
||||
|
||||
private:
|
||||
@ -985,6 +933,9 @@ private:
|
||||
SkScalar fTextSize;
|
||||
SkScalar fTextScaleX;
|
||||
SkScalar fTextSkewX;
|
||||
#ifdef SK_SUPPORT_HINTING_SCALE_FACTOR
|
||||
SkScalar fHintingScaleFactor;
|
||||
#endif
|
||||
|
||||
SkPathEffect* fPathEffect;
|
||||
SkShader* fShader;
|
||||
@ -1007,8 +958,11 @@ private:
|
||||
unsigned fStyle : 2;
|
||||
unsigned fTextEncoding : 2; // 3 values
|
||||
unsigned fHinting : 2;
|
||||
//unsigned fFreeBits : 4;
|
||||
unsigned fPrivFlags : 4; // these are not flattened/unflattened
|
||||
|
||||
enum PrivFlags {
|
||||
kNoDrawAnnotation_PrivFlag = 1 << 0,
|
||||
};
|
||||
|
||||
SkDrawCacheProc getDrawCacheProc() const;
|
||||
SkMeasureCacheProc getMeasureCacheProc(TextBufferDirection dir,
|
||||
@ -1026,59 +980,16 @@ private:
|
||||
static void Term();
|
||||
|
||||
enum {
|
||||
/* This is the size we use when we ask for a glyph's path. We then
|
||||
* post-transform it as we draw to match the request.
|
||||
* This is done to try to re-use cache entries for the path.
|
||||
*
|
||||
* This value is somewhat arbitrary. In theory, it could be 1, since
|
||||
* we store paths as floats. However, we get the path from the font
|
||||
* scaler, and it may represent its paths as fixed-point (or 26.6),
|
||||
* so we shouldn't ask for something too big (might overflow 16.16)
|
||||
* or too small (underflow 26.6).
|
||||
*
|
||||
* This value could track kMaxSizeForGlyphCache, assuming the above
|
||||
* constraints, but since we ask for unhinted paths, the two values
|
||||
* need not match per-se.
|
||||
*/
|
||||
kCanonicalTextSizeForPaths = 64,
|
||||
|
||||
/*
|
||||
* Above this size (taking into account CTM and textSize), we never use
|
||||
* the cache for bits or metrics (we might overflow), so we just ask
|
||||
* for a caononical size and post-transform that.
|
||||
*/
|
||||
kMaxSizeForGlyphCache = 256,
|
||||
kCanonicalTextSizeForPaths = 64
|
||||
};
|
||||
|
||||
static bool TooBigToUseCache(const SkMatrix& ctm, const SkMatrix& textM);
|
||||
|
||||
bool tooBigToUseCache() const;
|
||||
bool tooBigToUseCache(const SkMatrix& ctm) const;
|
||||
|
||||
// Set flags/hinting/textSize up to use for drawing text as paths.
|
||||
// Returns scale factor to restore the original textSize, since will will
|
||||
// have change it to kCanonicalTextSizeForPaths.
|
||||
SkScalar setupForAsPaths();
|
||||
|
||||
static SkScalar MaxCacheSize2() {
|
||||
static const SkScalar kMaxSize = SkIntToScalar(kMaxSizeForGlyphCache);
|
||||
static const SkScalar kMag2Max = kMaxSize * kMaxSize;
|
||||
return kMag2Max;
|
||||
}
|
||||
|
||||
friend class SkAutoGlyphCache;
|
||||
friend class SkCanvas;
|
||||
friend class SkDraw;
|
||||
friend class SkGraphics; // So Term() can be called.
|
||||
friend class SkPDFDevice;
|
||||
friend class GrBitmapTextContext;
|
||||
friend class GrDistanceFieldTextContext;
|
||||
friend class SkTextToPathIter;
|
||||
friend class SkCanonicalizePaint;
|
||||
|
||||
#ifdef SK_BUILD_FOR_ANDROID
|
||||
SkPaintOptionsAndroid fPaintOptionsAndroid;
|
||||
|
||||
// In order for the == operator to work properly this must be the last field
|
||||
// in the struct so that we can do a memcmp to this field's offset.
|
||||
uint32_t fGenerationID;
|
@ -12,16 +12,28 @@
|
||||
|
||||
#include "SkInstCnt.h"
|
||||
#include "SkMatrix.h"
|
||||
#include "SkPathRef.h"
|
||||
#include "SkTDArray.h"
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
#ifdef SK_BUILD_FOR_ANDROID
|
||||
#define GEN_ID_INC fGenerationID++
|
||||
#define GEN_ID_PTR_INC(ptr) ptr->fGenerationID++
|
||||
#else
|
||||
#define GEN_ID_INC
|
||||
#define GEN_ID_PTR_INC(ptr)
|
||||
#endif
|
||||
|
||||
class SkReader32;
|
||||
class SkWriter32;
|
||||
class SkAutoPathBoundsUpdate;
|
||||
class SkString;
|
||||
class SkPathRef;
|
||||
class SkRRect;
|
||||
|
||||
#ifndef SK_DEBUG_PATH_REF
|
||||
#define SK_DEBUG_PATH_REF 0
|
||||
#endif
|
||||
|
||||
/** \class SkPath
|
||||
|
||||
The SkPath class encapsulates compound (multiple contour) geometric paths
|
||||
@ -36,6 +48,7 @@ public:
|
||||
~SkPath();
|
||||
|
||||
SkPath& operator=(const SkPath&);
|
||||
|
||||
friend SK_API bool operator==(const SkPath&, const SkPath&);
|
||||
friend bool operator!=(const SkPath& a, const SkPath& b) {
|
||||
return !(a == b);
|
||||
@ -72,6 +85,7 @@ public:
|
||||
*/
|
||||
void setFillType(FillType ft) {
|
||||
fFillType = SkToU8(ft);
|
||||
GEN_ID_INC;
|
||||
}
|
||||
|
||||
/** Returns true if the filltype is one of the Inverse variants */
|
||||
@ -83,7 +97,8 @@ public:
|
||||
*/
|
||||
void toggleInverseFillType() {
|
||||
fFillType ^= 2;
|
||||
}
|
||||
GEN_ID_INC;
|
||||
}
|
||||
|
||||
enum Convexity {
|
||||
kUnknown_Convexity,
|
||||
@ -123,6 +138,7 @@ public:
|
||||
void setConvexity(Convexity);
|
||||
|
||||
/**
|
||||
* DEPRECATED: use getConvexity()
|
||||
* Returns true if the path is flagged as being convex. This is not a
|
||||
* confirmed by any analysis, it is just the value set earlier.
|
||||
*/
|
||||
@ -131,12 +147,12 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: use setConvexity()
|
||||
* Set the isConvex flag to true or false. Convex paths may draw faster if
|
||||
* this flag is set, though setting this to true on a path that is in fact
|
||||
* not convex can give undefined results when drawn. Paths default to
|
||||
* isConvex == false
|
||||
*/
|
||||
SK_ATTR_DEPRECATED("use setConvexity")
|
||||
void setIsConvex(bool isConvex) {
|
||||
this->setConvexity(isConvex ? kConvex_Convexity : kConcave_Convexity);
|
||||
}
|
||||
@ -151,18 +167,18 @@ public:
|
||||
* optimization for performance and so some paths that are in
|
||||
* fact ovals can report false.
|
||||
*/
|
||||
bool isOval(SkRect* rect) const { return fPathRef->isOval(rect); }
|
||||
bool isOval(SkRect* rect) const;
|
||||
|
||||
/** Clear any lines and curves from the path, making it empty. This frees up
|
||||
internal storage associated with those segments.
|
||||
On Android, does not change fSourcePath.
|
||||
This does NOT change the fill-type setting nor isConvex
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/** Similar to reset(), in that all lines and curves are removed from the
|
||||
path. However, any internal storage for those lines/curves is retained,
|
||||
making reuse of the path potentially faster.
|
||||
On Android, does not change fSourcePath.
|
||||
This does NOT change the fill-type setting nor isConvex
|
||||
*/
|
||||
void rewind();
|
||||
|
||||
@ -170,18 +186,17 @@ public:
|
||||
|
||||
@return true if the path is empty (contains no lines or curves)
|
||||
*/
|
||||
bool isEmpty() const {
|
||||
SkDEBUGCODE(this->validate();)
|
||||
return 0 == fPathRef->countVerbs();
|
||||
}
|
||||
bool isEmpty() const;
|
||||
|
||||
/**
|
||||
* Returns true if all of the points in this path are finite, meaning there
|
||||
* are no infinities and no NaNs.
|
||||
*/
|
||||
bool isFinite() const {
|
||||
SkDEBUGCODE(this->validate();)
|
||||
return fPathRef->isFinite();
|
||||
if (fBoundsIsDirty) {
|
||||
this->computeBounds();
|
||||
}
|
||||
return SkToBool(fIsFinite);
|
||||
}
|
||||
|
||||
/** Test a line for zero length
|
||||
@ -231,6 +246,16 @@ public:
|
||||
*/
|
||||
bool isRect(SkRect* rect) const;
|
||||
|
||||
/** Returns true if the path specifies a pair of nested rectangles. If so, and if
|
||||
rect is not null, set rect[0] to the outer rectangle and rect[1] to the inner
|
||||
rectangle. If the path does not specify a pair of nested rectangles, return
|
||||
false and ignore rect.
|
||||
|
||||
@param rect If not null, returns the path as a pair of nested rectangles
|
||||
@return true if the path describes a pair of nested rectangles
|
||||
*/
|
||||
bool isNestedRects(SkRect rect[2]) const;
|
||||
|
||||
/** Return the number of points in the path
|
||||
*/
|
||||
int countPoints() const;
|
||||
@ -271,7 +296,10 @@ public:
|
||||
do not extend as far as their control points.
|
||||
*/
|
||||
const SkRect& getBounds() const {
|
||||
return fPathRef->getBounds();
|
||||
if (fBoundsIsDirty) {
|
||||
this->computeBounds();
|
||||
}
|
||||
return fBounds;
|
||||
}
|
||||
|
||||
/** Calling this will, if the internal cache of the bounds is out of date,
|
||||
@ -395,14 +423,6 @@ public:
|
||||
*/
|
||||
void rQuadTo(SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2);
|
||||
|
||||
void conicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
|
||||
SkScalar w);
|
||||
void conicTo(const SkPoint& p1, const SkPoint& p2, SkScalar w) {
|
||||
this->conicTo(p1.fX, p1.fY, p2.fX, p2.fY, w);
|
||||
}
|
||||
void rConicTo(SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2,
|
||||
SkScalar w);
|
||||
|
||||
/** Add a cubic bezier from the last point, approaching control points
|
||||
(x1,y1) and (x2,y2), and ending at (x3,y3). If no moveTo() call has been
|
||||
made for this contour, the first point is automatically set to (0,0).
|
||||
@ -446,8 +466,8 @@ public:
|
||||
@param dy3 The amount to add to the y-coordinate of the last point on
|
||||
this contour, to specify the end point of a cubic curve
|
||||
*/
|
||||
void rCubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
|
||||
SkScalar x3, SkScalar y3);
|
||||
void rCubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
|
||||
SkScalar x3, SkScalar y3);
|
||||
|
||||
/** Append the specified arc to the path as a new contour. If the start of
|
||||
the path is different from the path's current last point, then an
|
||||
@ -461,8 +481,8 @@ public:
|
||||
treated mod 360.
|
||||
@param forceMoveTo If true, always begin a new contour with the arc
|
||||
*/
|
||||
void arcTo(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
|
||||
bool forceMoveTo);
|
||||
void arcTo(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
|
||||
bool forceMoveTo);
|
||||
|
||||
/** Append a line and arc to the current path. This is the same as the
|
||||
PostScript call "arct".
|
||||
@ -555,25 +575,6 @@ public:
|
||||
return computedDir == dir;
|
||||
}
|
||||
|
||||
enum PathAsRect {
|
||||
/** The path can not draw the same as its bounds. */
|
||||
kNone_PathAsRect,
|
||||
/** The path draws the same as its bounds when filled. */
|
||||
kFill_PathAsRect,
|
||||
/** The path draws the same as its bounds when stroked or filled. */
|
||||
kStroke_PathAsRect,
|
||||
};
|
||||
|
||||
/** Returns kFill_PathAsRect or kStroke_PathAsRect if drawing the path (either filled or
|
||||
stroked) will be equivalent to filling/stroking the path's bounding rect. If
|
||||
either is true, and direction is not null, sets the direction of the contour. If the
|
||||
path is not drawn equivalent to a rect, returns kNone_PathAsRect and ignores direction.
|
||||
|
||||
@param direction If not null, set to the contour's direction when it is drawn as a rect
|
||||
@return the path's PathAsRect type
|
||||
*/
|
||||
PathAsRect asRect(Direction* direction = NULL) const;
|
||||
|
||||
/** Returns true if the path specifies a rectangle. If so, and if isClosed is
|
||||
not null, set isClosed to true if the path is closed. Also, if returning true
|
||||
and direction is not null, return the rect direction. If the path does not
|
||||
@ -585,26 +586,13 @@ public:
|
||||
*/
|
||||
bool isRect(bool* isClosed, Direction* direction) const;
|
||||
|
||||
/** Returns true if the path specifies a pair of nested rectangles. If so, and if
|
||||
rect is not null, set rect[0] to the outer rectangle and rect[1] to the inner
|
||||
rectangle. If so, and dirs is not null, set dirs[0] to the direction of
|
||||
the outer rectangle and dirs[1] to the direction of the inner rectangle. If
|
||||
the path does not specify a pair of nested rectangles, return
|
||||
false and ignore rect and dirs.
|
||||
|
||||
@param rect If not null, returns the path as a pair of nested rectangles
|
||||
@param dirs If not null, returns the direction of the rects
|
||||
@return true if the path describes a pair of nested rectangles
|
||||
*/
|
||||
bool isNestedRects(SkRect rect[2], Direction dirs[2] = NULL) const;
|
||||
|
||||
/**
|
||||
* Add a closed rectangle contour to the path
|
||||
* @param rect The rectangle to add as a closed contour to the path
|
||||
* @param dir The direction to wind the rectangle's contour. Cannot be
|
||||
* kUnknown_Direction.
|
||||
*/
|
||||
void addRect(const SkRect& rect, Direction dir = kCW_Direction);
|
||||
void addRect(const SkRect& rect, Direction dir = kCW_Direction);
|
||||
|
||||
/**
|
||||
* Add a closed rectangle contour to the path
|
||||
@ -663,8 +651,8 @@ public:
|
||||
* @param dir The direction to wind the rectangle's contour. Cannot be
|
||||
* kUnknown_Direction.
|
||||
*/
|
||||
void addRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry,
|
||||
Direction dir = kCW_Direction);
|
||||
void addRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry,
|
||||
Direction dir = kCW_Direction);
|
||||
|
||||
/**
|
||||
* Add a closed round-rectangle contour to the path. Each corner receives
|
||||
@ -702,41 +690,25 @@ public:
|
||||
*/
|
||||
void addPoly(const SkPoint pts[], int count, bool close);
|
||||
|
||||
enum AddPathMode {
|
||||
/** Source path contours are added as new contours.
|
||||
*/
|
||||
kAppend_AddPathMode,
|
||||
/** Path is added by extending the last contour of the destination path
|
||||
with the first contour of the source path. If the last contour of
|
||||
the destination path is closed, then it will not be extended.
|
||||
Instead, the start of source path will be extended by a straight
|
||||
line to the end point of the destination path.
|
||||
*/
|
||||
kExtend_AddPathMode
|
||||
};
|
||||
|
||||
/** Add a copy of src to the path, offset by (dx,dy)
|
||||
@param src The path to add as a new contour
|
||||
@param dx The amount to translate the path in X as it is added
|
||||
@param dx The amount to translate the path in Y as it is added
|
||||
*/
|
||||
void addPath(const SkPath& src, SkScalar dx, SkScalar dy,
|
||||
AddPathMode mode = kAppend_AddPathMode);
|
||||
void addPath(const SkPath& src, SkScalar dx, SkScalar dy);
|
||||
|
||||
/** Add a copy of src to the path
|
||||
*/
|
||||
void addPath(const SkPath& src, AddPathMode mode = kAppend_AddPathMode) {
|
||||
void addPath(const SkPath& src) {
|
||||
SkMatrix m;
|
||||
m.reset();
|
||||
this->addPath(src, m, mode);
|
||||
this->addPath(src, m);
|
||||
}
|
||||
|
||||
/** Add a copy of src to the path, transformed by matrix
|
||||
@param src The path to add as a new contour
|
||||
@param matrix Transform applied to src
|
||||
@param mode Determines how path is added
|
||||
*/
|
||||
void addPath(const SkPath& src, const SkMatrix& matrix, AddPathMode mode = kAppend_AddPathMode);
|
||||
void addPath(const SkPath& src, const SkMatrix& matrix);
|
||||
|
||||
/**
|
||||
* Same as addPath(), but reverses the src input
|
||||
@ -804,8 +776,7 @@ public:
|
||||
enum SegmentMask {
|
||||
kLine_SegmentMask = 1 << 0,
|
||||
kQuad_SegmentMask = 1 << 1,
|
||||
kConic_SegmentMask = 1 << 2,
|
||||
kCubic_SegmentMask = 1 << 3,
|
||||
kCubic_SegmentMask = 1 << 2
|
||||
};
|
||||
|
||||
/**
|
||||
@ -813,16 +784,15 @@ public:
|
||||
* set if the path contains 1 or more segments of that type.
|
||||
* Returns 0 for an empty path (no segments).
|
||||
*/
|
||||
uint32_t getSegmentMasks() const { return fPathRef->getSegmentMasks(); }
|
||||
uint32_t getSegmentMasks() const { return fSegmentMask; }
|
||||
|
||||
enum Verb {
|
||||
kMove_Verb, //!< iter.next returns 1 point
|
||||
kLine_Verb, //!< iter.next returns 2 points
|
||||
kQuad_Verb, //!< iter.next returns 3 points
|
||||
kConic_Verb, //!< iter.next returns 3 points + iter.conicWeight()
|
||||
kCubic_Verb, //!< iter.next returns 4 points
|
||||
kClose_Verb, //!< iter.next returns 1 point (contour's moveTo pt)
|
||||
kDone_Verb, //!< iter.next returns 0 points
|
||||
kDone_Verb //!< iter.next returns 0 points
|
||||
};
|
||||
|
||||
/** Iterate through all of the segments (lines, quadratics, cubics) of
|
||||
@ -856,12 +826,6 @@ public:
|
||||
return this->doNext(pts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the weight for the current conic. Only valid if the current
|
||||
* segment return by next() was a conic.
|
||||
*/
|
||||
SkScalar conicWeight() const { return *fConicWeights; }
|
||||
|
||||
/** If next() returns kLine_Verb, then this query returns true if the
|
||||
line was the result of a close() command (i.e. the end point is the
|
||||
initial moveto for this contour). If next() returned a different
|
||||
@ -881,7 +845,6 @@ public:
|
||||
const SkPoint* fPts;
|
||||
const uint8_t* fVerbs;
|
||||
const uint8_t* fVerbStop;
|
||||
const SkScalar* fConicWeights;
|
||||
SkPoint fMoveTo;
|
||||
SkPoint fLastPt;
|
||||
SkBool8 fForceClose;
|
||||
@ -913,13 +876,10 @@ public:
|
||||
*/
|
||||
Verb next(SkPoint pts[4]);
|
||||
|
||||
SkScalar conicWeight() const { return *fConicWeights; }
|
||||
|
||||
private:
|
||||
const SkPoint* fPts;
|
||||
const uint8_t* fVerbs;
|
||||
const uint8_t* fVerbStop;
|
||||
const SkScalar* fConicWeights;
|
||||
SkPoint fMoveTo;
|
||||
SkPoint fLastPt;
|
||||
};
|
||||
@ -934,73 +894,84 @@ public:
|
||||
void dump() const;
|
||||
|
||||
/**
|
||||
* Write the path to the buffer, and return the number of bytes written.
|
||||
* Write the region to the buffer, and return the number of bytes written.
|
||||
* If buffer is NULL, it still returns the number of bytes.
|
||||
*/
|
||||
size_t writeToMemory(void* buffer) const;
|
||||
uint32_t writeToMemory(void* buffer) const;
|
||||
/**
|
||||
* Initializes the path from the buffer
|
||||
*
|
||||
* @param buffer Memory to read from
|
||||
* @param length Amount of memory available in the buffer
|
||||
* @return number of bytes read (must be a multiple of 4) or
|
||||
* 0 if there was not enough memory available
|
||||
* Initialized the region from the buffer, returning the number
|
||||
* of bytes actually read.
|
||||
*/
|
||||
size_t readFromMemory(const void* buffer, size_t length);
|
||||
|
||||
/** Returns a non-zero, globally unique value corresponding to the set of verbs
|
||||
and points in the path (but not the fill type [except on Android skbug.com/1762]).
|
||||
Each time the path is modified, a different generation ID will be returned.
|
||||
*/
|
||||
uint32_t getGenerationID() const;
|
||||
uint32_t readFromMemory(const void* buffer);
|
||||
|
||||
#ifdef SK_BUILD_FOR_ANDROID
|
||||
static const int kPathRefGenIDBitCnt = 30; // leave room for the fill type (skbug.com/1762)
|
||||
uint32_t getGenerationID() const;
|
||||
const SkPath* getSourcePath() const;
|
||||
void setSourcePath(const SkPath* path);
|
||||
#else
|
||||
static const int kPathRefGenIDBitCnt = 32;
|
||||
#endif
|
||||
|
||||
SkDEBUGCODE(void validate() const;)
|
||||
|
||||
private:
|
||||
enum SerializationOffsets {
|
||||
// 1 free bit at 29
|
||||
kUnused1_SerializationShift = 28, // 1 free bit
|
||||
kDirection_SerializationShift = 26, // requires 2 bits
|
||||
kUnused2_SerializationShift = 25, // 1 free bit
|
||||
// 1 free bit at 24
|
||||
kConvexity_SerializationShift = 16, // requires 8 bits
|
||||
kFillType_SerializationShift = 8, // requires 8 bits
|
||||
// 8 free bits at 0
|
||||
kIsFinite_SerializationShift = 25, // requires 1 bit
|
||||
kIsOval_SerializationShift = 24, // requires 1 bit
|
||||
kConvexity_SerializationShift = 16, // requires 2 bits
|
||||
kFillType_SerializationShift = 8, // requires 2 bits
|
||||
kSegmentMask_SerializationShift = 0 // requires 3 bits
|
||||
};
|
||||
|
||||
SkAutoTUnref<SkPathRef> fPathRef;
|
||||
#if SK_DEBUG_PATH_REF
|
||||
public:
|
||||
/** Debugging wrapper for SkAutoTUnref<SkPathRef> used to track owners (SkPaths)
|
||||
of SkPathRefs */
|
||||
class PathRefDebugRef {
|
||||
public:
|
||||
PathRefDebugRef(SkPath* owner);
|
||||
PathRefDebugRef(SkPathRef* pr, SkPath* owner);
|
||||
~PathRefDebugRef();
|
||||
void reset(SkPathRef* ref);
|
||||
void swap(PathRefDebugRef* other);
|
||||
SkPathRef* get() const;
|
||||
SkAutoTUnref<SkPathRef>::BlockRefType *operator->() const;
|
||||
operator SkPathRef*();
|
||||
private:
|
||||
SkAutoTUnref<SkPathRef> fPathRef;
|
||||
SkPath* fOwner;
|
||||
};
|
||||
|
||||
private:
|
||||
PathRefDebugRef fPathRef;
|
||||
#else
|
||||
SkAutoTUnref<SkPathRef> fPathRef;
|
||||
#endif
|
||||
|
||||
mutable SkRect fBounds;
|
||||
int fLastMoveToIndex;
|
||||
uint8_t fFillType;
|
||||
uint8_t fSegmentMask;
|
||||
mutable uint8_t fBoundsIsDirty;
|
||||
mutable uint8_t fConvexity;
|
||||
mutable uint8_t fDirection;
|
||||
mutable SkBool8 fIsFinite; // only meaningful if bounds are valid
|
||||
mutable SkBool8 fIsOval;
|
||||
#ifdef SK_BUILD_FOR_ANDROID
|
||||
uint32_t fGenerationID;
|
||||
const SkPath* fSourcePath;
|
||||
#endif
|
||||
|
||||
/** Resets all fields other than fPathRef to their initial 'empty' values.
|
||||
* Assumes the caller has already emptied fPathRef.
|
||||
* On Android increments fGenerationID without reseting it.
|
||||
*/
|
||||
void resetFields();
|
||||
|
||||
/** Sets all fields other than fPathRef to the values in 'that'.
|
||||
* Assumes the caller has already set fPathRef.
|
||||
* Doesn't change fGenerationID or fSourcePath on Android.
|
||||
*/
|
||||
void copyFields(const SkPath& that);
|
||||
// called, if dirty, by getBounds()
|
||||
void computeBounds() const;
|
||||
|
||||
friend class Iter;
|
||||
|
||||
friend class SkPathStroker;
|
||||
/* Append the first contour of path, ignoring path's initial point. If no
|
||||
moveTo() call has been made for this contour, the first point is
|
||||
automatically set to (0,0).
|
||||
*/
|
||||
void pathTo(const SkPath& path);
|
||||
|
||||
/* Append, in reverse order, the first contour of path, ignoring path's
|
||||
last point. If no moveTo() call has been made for this contour, the
|
||||
@ -1023,27 +994,10 @@ private:
|
||||
bool isRectContour(bool allowPartial, int* currVerb, const SkPoint** pts,
|
||||
bool* isClosed, Direction* direction) const;
|
||||
|
||||
/** Returns if the path can return a bound at no cost (true) or will have to
|
||||
perform some computation (false).
|
||||
*/
|
||||
bool hasComputedBounds() const {
|
||||
SkDEBUGCODE(this->validate();)
|
||||
return fPathRef->hasComputedBounds();
|
||||
}
|
||||
|
||||
|
||||
// 'rect' needs to be sorted
|
||||
void setBounds(const SkRect& rect) {
|
||||
SkPathRef::Editor ed(&fPathRef);
|
||||
|
||||
ed.setBounds(rect);
|
||||
}
|
||||
|
||||
friend class SkAutoPathBoundsUpdate;
|
||||
friend class SkAutoDisableOvalCheck;
|
||||
friend class SkAutoDisableDirectionCheck;
|
||||
friend class SkBench_AddPathTest; // perf test reversePathTo
|
||||
friend class PathTest_Private; // unit test reversePathTo
|
||||
friend class SkBench_AddPathTest; // perf test pathTo/reversePathTo
|
||||
};
|
||||
|
||||
#endif
|
@ -106,10 +106,8 @@ public:
|
||||
const SkStrokeRec&, const SkMatrix&,
|
||||
const SkRect* cullR) const;
|
||||
|
||||
SK_DEFINE_FLATTENABLE_TYPE(SkPathEffect)
|
||||
|
||||
protected:
|
||||
SkPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {}
|
||||
SkPathEffect(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
|
||||
|
||||
private:
|
||||
// illegal
|
||||
@ -131,8 +129,8 @@ public:
|
||||
virtual ~SkPairPathEffect();
|
||||
|
||||
protected:
|
||||
SkPairPathEffect(SkReadBuffer&);
|
||||
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
|
||||
SkPairPathEffect(SkFlattenableReadBuffer&);
|
||||
virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
|
||||
|
||||
// these are visible to our subclasses
|
||||
SkPathEffect* fPE0, *fPE1;
|
||||
@ -162,7 +160,7 @@ public:
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposePathEffect)
|
||||
|
||||
protected:
|
||||
SkComposePathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {}
|
||||
SkComposePathEffect(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
|
||||
|
||||
private:
|
||||
// illegal
|
||||
@ -193,7 +191,7 @@ public:
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSumPathEffect)
|
||||
|
||||
protected:
|
||||
SkSumPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {}
|
||||
SkSumPathEffect(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
|
||||
|
||||
private:
|
||||
// illegal
|
@ -1,3 +1,4 @@
|
||||
|
||||
/*
|
||||
* Copyright 2006 The Android Open Source Project
|
||||
*
|
||||
@ -5,13 +6,14 @@
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SkPathMeasure_DEFINED
|
||||
#define SkPathMeasure_DEFINED
|
||||
|
||||
#include "SkPath.h"
|
||||
#include "SkTDArray.h"
|
||||
|
||||
class SK_API SkPathMeasure : SkNoncopyable {
|
||||
class SkPathMeasure : SkNoncopyable {
|
||||
public:
|
||||
SkPathMeasure();
|
||||
/** Initialize the pathmeasure with the specified path. The path must remain valid
|
@ -11,20 +11,15 @@
|
||||
#define SkPicture_DEFINED
|
||||
|
||||
#include "SkBitmap.h"
|
||||
#include "SkImageDecoder.h"
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
class SkBBoxHierarchy;
|
||||
class SkCanvas;
|
||||
class SkDrawPictureCallback;
|
||||
class SkData;
|
||||
class SkPicturePlayback;
|
||||
class SkPictureRecord;
|
||||
class SkStream;
|
||||
class SkWStream;
|
||||
|
||||
struct SkPictInfo;
|
||||
|
||||
/** \class SkPicture
|
||||
|
||||
The SkPicture class records the drawing commands made to a canvas, to
|
||||
@ -44,6 +39,13 @@ public:
|
||||
*/
|
||||
SkPicture(const SkPicture& src);
|
||||
|
||||
/**
|
||||
* Recreate a picture that was serialized into a stream.
|
||||
* On failure, silently creates an empty picture.
|
||||
* @param SkStream Serialized picture data.
|
||||
*/
|
||||
explicit SkPicture(SkStream*);
|
||||
|
||||
/**
|
||||
* Function signature defining a function that sets up an SkBitmap from encoded data. On
|
||||
* success, the SkBitmap should have its Config, width, height, rowBytes and pixelref set.
|
||||
@ -60,23 +62,12 @@ public:
|
||||
/**
|
||||
* Recreate a picture that was serialized into a stream.
|
||||
* @param SkStream Serialized picture data.
|
||||
* @param success Output parameter. If non-NULL, will be set to true if the picture was
|
||||
* deserialized successfully and false otherwise.
|
||||
* @param proc Function pointer for installing pixelrefs on SkBitmaps representing the
|
||||
* encoded bitmap data from the stream.
|
||||
* @return A new SkPicture representing the serialized data, or NULL if the stream is
|
||||
* invalid.
|
||||
*/
|
||||
static SkPicture* CreateFromStream(SkStream*,
|
||||
InstallPixelRefProc proc = &SkImageDecoder::DecodeMemory);
|
||||
|
||||
/**
|
||||
* Recreate a picture that was serialized into a buffer. If the creation requires bitmap
|
||||
* decoding, the decoder must be set on the SkReadBuffer parameter by calling
|
||||
* SkReadBuffer::setBitmapDecoder() before calling SkPicture::CreateFromBuffer().
|
||||
* @param SkReadBuffer Serialized picture data.
|
||||
* @return A new SkPicture representing the serialized data, or NULL if the buffer is
|
||||
* invalid.
|
||||
*/
|
||||
static SkPicture* CreateFromBuffer(SkReadBuffer&);
|
||||
SkPicture(SkStream*, bool* success, InstallPixelRefProc proc);
|
||||
|
||||
virtual ~SkPicture();
|
||||
|
||||
@ -124,16 +115,7 @@ public:
|
||||
Note: Currently this is not serializable, the bounding data will be
|
||||
discarded if you serialize into a stream and then deserialize.
|
||||
*/
|
||||
kOptimizeForClippedPlayback_RecordingFlag = 0x02,
|
||||
/*
|
||||
This flag disables all the picture recording optimizations (i.e.,
|
||||
those in SkPictureRecord). It is mainly intended for testing the
|
||||
existing optimizations (i.e., to actually have the pattern
|
||||
appear in an .skp we have to disable the optimization). This
|
||||
option doesn't affect the optimizations controlled by
|
||||
'kOptimizeForClippedPlayback_RecordingFlag'.
|
||||
*/
|
||||
kDisableRecordOptimizations_RecordingFlag = 0x04
|
||||
kOptimizeForClippedPlayback_RecordingFlag = 0x02
|
||||
};
|
||||
|
||||
/** Returns the canvas that records the drawing commands.
|
||||
@ -159,9 +141,9 @@ public:
|
||||
|
||||
/** Replays the drawing commands on the specified canvas. This internally
|
||||
calls endRecording() if that has not already been called.
|
||||
@param canvas the canvas receiving the drawing commands.
|
||||
@param surface the canvas receiving the drawing commands.
|
||||
*/
|
||||
void draw(SkCanvas* canvas, SkDrawPictureCallback* = NULL);
|
||||
void draw(SkCanvas* surface);
|
||||
|
||||
/** Return the width of the picture's recording canvas. This
|
||||
value reflects what was passed to setSize(), and does not necessarily
|
||||
@ -178,36 +160,20 @@ public:
|
||||
int height() const { return fHeight; }
|
||||
|
||||
/**
|
||||
* Function to encode an SkBitmap to an SkData. A function with this
|
||||
* signature can be passed to serialize() and SkWriteBuffer.
|
||||
* Returning NULL will tell the SkWriteBuffer to use
|
||||
* SkBitmap::flatten() to store the bitmap.
|
||||
*
|
||||
* @param pixelRefOffset DEPRECATED -- caller assumes it will return 0.
|
||||
* @return SkData If non-NULL, holds encoded data representing the passed
|
||||
* in bitmap. The caller is responsible for calling unref().
|
||||
* Function to encode an SkBitmap to an SkWStream. A function with this
|
||||
* signature can be passed to serialize() and SkOrderedWriteBuffer. The
|
||||
* function should return true if it succeeds. Otherwise it should return
|
||||
* false so that SkOrderedWriteBuffer can switch to another method of
|
||||
* storing SkBitmaps.
|
||||
*/
|
||||
typedef SkData* (*EncodeBitmap)(size_t* pixelRefOffset, const SkBitmap& bm);
|
||||
typedef bool (*EncodeBitmap)(SkWStream*, const SkBitmap&);
|
||||
|
||||
/**
|
||||
* Serialize to a stream. If non NULL, encoder will be used to encode
|
||||
* any bitmaps in the picture.
|
||||
* encoder will never be called with a NULL pixelRefOffset.
|
||||
*/
|
||||
void serialize(SkWStream*, EncodeBitmap encoder = NULL) const;
|
||||
|
||||
/**
|
||||
* Serialize to a buffer.
|
||||
*/
|
||||
void flatten(SkWriteBuffer&) const;
|
||||
|
||||
/**
|
||||
* Returns true if any bitmaps may be produced when this SkPicture
|
||||
* is replayed.
|
||||
* Returns false if called while still recording.
|
||||
*/
|
||||
bool willPlayBackBitmaps() const;
|
||||
|
||||
#ifdef SK_BUILD_FOR_ANDROID
|
||||
/** Signals that the caller is prematurely done replaying the drawing
|
||||
commands. This can be called from a canvas virtual while the picture
|
||||
@ -228,18 +194,7 @@ protected:
|
||||
// V9 : Allow the reader and writer of an SKP disagree on whether to support
|
||||
// SK_SUPPORT_HINTING_SCALE_FACTOR
|
||||
// V10: add drawRRect, drawOval, clipRRect
|
||||
// V11: modify how readBitmap and writeBitmap store their info.
|
||||
// V12: add conics to SkPath, use new SkPathRef flattening
|
||||
// V13: add flag to drawBitmapRectToRect
|
||||
// parameterize blurs by sigma rather than radius
|
||||
// V14: Add flags word to PathRef serialization
|
||||
// V15: Remove A1 bitmpa config (and renumber remaining configs)
|
||||
// V16: Move SkPath's isOval flag to SkPathRef
|
||||
// V17: SkPixelRef now writes SkImageInfo
|
||||
// V18: SkBitmap now records x,y for its pixelref origin, instead of offset.
|
||||
// V19: encode matrices and regions into the ops stream
|
||||
// V20: added bool to SkPictureImageFilter's serialization (to allow SkPicture serialization)
|
||||
static const uint32_t PICTURE_VERSION = 20;
|
||||
static const uint32_t PICTURE_VERSION = 10;
|
||||
|
||||
// fPlayback, fRecord, fWidth & fHeight are protected to allow derived classes to
|
||||
// install their own SkPicturePlayback-derived players,SkPictureRecord-derived
|
||||
@ -248,22 +203,12 @@ protected:
|
||||
SkPictureRecord* fRecord;
|
||||
int fWidth, fHeight;
|
||||
|
||||
// Create a new SkPicture from an existing SkPicturePlayback. Ref count of
|
||||
// playback is unchanged.
|
||||
SkPicture(SkPicturePlayback*, int width, int height);
|
||||
|
||||
// For testing. Derived classes may instantiate an alternate
|
||||
// SkBBoxHierarchy implementation
|
||||
virtual SkBBoxHierarchy* createBBoxHierarchy() const;
|
||||
|
||||
// Return true if the SkStream represents a serialized picture, and fills out
|
||||
// SkPictInfo. After this function returns, the SkStream is not rewound; it
|
||||
// will be ready to be parsed to create an SkPicturePlayback.
|
||||
// If false is returned, SkPictInfo is unmodified.
|
||||
static bool StreamIsSKP(SkStream*, SkPictInfo*);
|
||||
static bool BufferIsSKP(SkReadBuffer&, SkPictInfo*);
|
||||
private:
|
||||
void createHeader(void* header) const;
|
||||
void initFromStream(SkStream*, bool* success, InstallPixelRefProc);
|
||||
|
||||
friend class SkFlatPicture;
|
||||
friend class SkPicturePlayback;
|
||||
@ -271,22 +216,25 @@ private:
|
||||
typedef SkRefCnt INHERITED;
|
||||
};
|
||||
|
||||
/**
|
||||
* Subclasses of this can be passed to canvas.drawPicture. During the drawing
|
||||
* of the picture, this callback will periodically be invoked. If its
|
||||
* abortDrawing() returns true, then picture playback will be interrupted.
|
||||
*
|
||||
* The resulting drawing is undefined, as there is no guarantee how often the
|
||||
* callback will be invoked. If the abort happens inside some level of nested
|
||||
* calls to save(), restore will automatically be called to return the state
|
||||
* to the same level it was before the drawPicture call was made.
|
||||
*/
|
||||
class SK_API SkDrawPictureCallback {
|
||||
class SkAutoPictureRecord : SkNoncopyable {
|
||||
public:
|
||||
SkDrawPictureCallback() {}
|
||||
virtual ~SkDrawPictureCallback() {}
|
||||
SkAutoPictureRecord(SkPicture* pict, int width, int height,
|
||||
uint32_t recordingFlags = 0) {
|
||||
fPicture = pict;
|
||||
fCanvas = pict->beginRecording(width, height, recordingFlags);
|
||||
}
|
||||
~SkAutoPictureRecord() {
|
||||
fPicture->endRecording();
|
||||
}
|
||||
|
||||
virtual bool abortDrawing() = 0;
|
||||
/** Return the canvas to draw into for recording into the picture.
|
||||
*/
|
||||
SkCanvas* getRecordingCanvas() const { return fCanvas; }
|
||||
|
||||
private:
|
||||
SkPicture* fPicture;
|
||||
SkCanvas* fCanvas;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
@ -1,3 +1,4 @@
|
||||
|
||||
/*
|
||||
* Copyright 2008 The Android Open Source Project
|
||||
*
|
||||
@ -5,6 +6,7 @@
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SkPixelRef_DEFINED
|
||||
#define SkPixelRef_DEFINED
|
||||
|
||||
@ -12,10 +14,6 @@
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkString.h"
|
||||
#include "SkFlattenable.h"
|
||||
#include "SkImageInfo.h"
|
||||
#include "SkTDArray.h"
|
||||
|
||||
//#define xed
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
/**
|
||||
@ -36,7 +34,8 @@ class SkData;
|
||||
struct SkIRect;
|
||||
class SkMutex;
|
||||
|
||||
class GrTexture;
|
||||
// this is an opaque class, not interpreted by skia
|
||||
class SkGpuTexture;
|
||||
|
||||
/** \class SkPixelRef
|
||||
|
||||
@ -50,40 +49,16 @@ class SK_API SkPixelRef : public SkFlattenable {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkPixelRef)
|
||||
|
||||
explicit SkPixelRef(const SkImageInfo&);
|
||||
SkPixelRef(const SkImageInfo&, SkBaseMutex* mutex);
|
||||
virtual ~SkPixelRef();
|
||||
|
||||
const SkImageInfo& info() const {
|
||||
return fInfo;
|
||||
}
|
||||
explicit SkPixelRef(SkBaseMutex* mutex = NULL);
|
||||
|
||||
/** Return the pixel memory returned from lockPixels, or null if the
|
||||
lockCount is 0.
|
||||
*/
|
||||
void* pixels() const { return fRec.fPixels; }
|
||||
void* pixels() const { return fPixels; }
|
||||
|
||||
/** Return the current colorTable (if any) if pixels are locked, or null.
|
||||
*/
|
||||
SkColorTable* colorTable() const { return fRec.fColorTable; }
|
||||
|
||||
size_t rowBytes() const { return fRec.fRowBytes; }
|
||||
|
||||
/**
|
||||
* To access the actual pixels of a pixelref, it must be "locked".
|
||||
* Calling lockPixels returns a LockRec struct (on success).
|
||||
*/
|
||||
struct LockRec {
|
||||
void* fPixels;
|
||||
SkColorTable* fColorTable;
|
||||
size_t fRowBytes;
|
||||
|
||||
void zero() { sk_bzero(this, sizeof(*this)); }
|
||||
|
||||
bool isZero() const {
|
||||
return NULL == fPixels && NULL == fColorTable && 0 == fRowBytes;
|
||||
}
|
||||
};
|
||||
SkColorTable* colorTable() const { return fColorTable; }
|
||||
|
||||
/**
|
||||
* Returns true if the lockcount > 0
|
||||
@ -92,19 +67,10 @@ public:
|
||||
|
||||
SkDEBUGCODE(int getLockCount() const { return fLockCount; })
|
||||
|
||||
/**
|
||||
* Call to access the pixel memory. Return true on success. Balance this
|
||||
* with a call to unlockPixels().
|
||||
*/
|
||||
bool lockPixels();
|
||||
|
||||
/**
|
||||
* Call to access the pixel memory. On success, return true and fill out
|
||||
* the specified rec. On failure, return false and ignore the rec parameter.
|
||||
* Balance this with a call to unlockPixels().
|
||||
*/
|
||||
bool lockPixels(LockRec* rec);
|
||||
|
||||
/** Call to access the pixel memory, which is returned. Balance with a call
|
||||
to unlockPixels().
|
||||
*/
|
||||
void lockPixels();
|
||||
/** Call to balanace a previous call to lockPixels(). Returns the pixels
|
||||
(or null) after the unlock. NOTE: lock calls can be nested, but the
|
||||
matching number of unlock calls must be made in order to free the
|
||||
@ -126,20 +92,12 @@ public:
|
||||
*/
|
||||
uint32_t getGenerationID() const;
|
||||
|
||||
/**
|
||||
* Call this if you have changed the contents of the pixels. This will in-
|
||||
* turn cause a different generation ID value to be returned from
|
||||
* getGenerationID().
|
||||
*/
|
||||
/** Call this if you have changed the contents of the pixels. This will in-
|
||||
turn cause a different generation ID value to be returned from
|
||||
getGenerationID().
|
||||
*/
|
||||
void notifyPixelsChanged();
|
||||
|
||||
/**
|
||||
* Change the info's AlphaType. Note that this does not automatically
|
||||
* invalidate the generation ID. If the pixel values themselves have
|
||||
* changed, then you must explicitly call notifyPixelsChanged() as well.
|
||||
*/
|
||||
void changeAlphaType(SkAlphaType at);
|
||||
|
||||
/** Returns true if this pixelref is marked as immutable, meaning that the
|
||||
contents of its pixels will not change for the lifetime of the pixelref.
|
||||
*/
|
||||
@ -184,40 +142,9 @@ public:
|
||||
return this->onRefEncodedData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Experimental -- tells the caller if it is worth it to call decodeInto().
|
||||
* Just an optimization at this point, to avoid checking the cache first.
|
||||
* We may remove/change this call in the future.
|
||||
*/
|
||||
bool implementsDecodeInto() {
|
||||
return this->onImplementsDecodeInto();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a decoded instance of this pixelRef in bitmap. If this cannot be
|
||||
* done, return false and the bitmap parameter is ignored/unchanged.
|
||||
*
|
||||
* pow2 is the requeste power-of-two downscale that the caller needs. This
|
||||
* can be ignored, and the "original" size can be returned, but if the
|
||||
* underlying codec can efficiently return a smaller size, that should be
|
||||
* done. Some examples:
|
||||
*
|
||||
* To request the "base" version (original scale), pass 0 for pow2
|
||||
* To request 1/2 scale version (1/2 width, 1/2 height), pass 1 for pow2
|
||||
* To request 1/4 scale version (1/4 width, 1/4 height), pass 2 for pow2
|
||||
* ...
|
||||
*
|
||||
* If this returns true, then bitmap must be "locked" such that
|
||||
* bitmap->getPixels() will return the correct address.
|
||||
*/
|
||||
bool decodeInto(int pow2, SkBitmap* bitmap) {
|
||||
SkASSERT(pow2 >= 0);
|
||||
return this->onDecodeInto(pow2, bitmap);
|
||||
}
|
||||
|
||||
/** Are we really wrapping a texture instead of a bitmap?
|
||||
*/
|
||||
virtual GrTexture* getTexture() { return NULL; }
|
||||
virtual SkGpuTexture* getTexture() { return NULL; }
|
||||
|
||||
bool readPixels(SkBitmap* dst, const SkIRect* subset = NULL);
|
||||
|
||||
@ -250,52 +177,20 @@ public:
|
||||
virtual void globalUnref();
|
||||
#endif
|
||||
|
||||
SK_DEFINE_FLATTENABLE_TYPE(SkPixelRef)
|
||||
|
||||
// Register a listener that may be called the next time our generation ID changes.
|
||||
//
|
||||
// We'll only call the listener if we're confident that we are the only SkPixelRef with this
|
||||
// generation ID. If our generation ID changes and we decide not to call the listener, we'll
|
||||
// never call it: you must add a new listener for each generation ID change. We also won't call
|
||||
// the listener when we're certain no one knows what our generation ID is.
|
||||
//
|
||||
// This can be used to invalidate caches keyed by SkPixelRef generation ID.
|
||||
struct GenIDChangeListener {
|
||||
virtual ~GenIDChangeListener() {}
|
||||
virtual void onChange() = 0;
|
||||
};
|
||||
|
||||
// Takes ownership of listener.
|
||||
void addGenIDChangeListener(GenIDChangeListener* listener);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* On success, returns true and fills out the LockRec for the pixels. On
|
||||
* failure returns false and ignores the LockRec parameter.
|
||||
*
|
||||
* The caller will have already acquired a mutex for thread safety, so this
|
||||
* method need not do that.
|
||||
*/
|
||||
virtual bool onNewLockPixels(LockRec*) = 0;
|
||||
|
||||
/**
|
||||
* Balancing the previous successful call to onNewLockPixels. The locked
|
||||
* pixel address will no longer be referenced, so the subclass is free to
|
||||
* move or discard that memory.
|
||||
*
|
||||
* The caller will have already acquired a mutex for thread safety, so this
|
||||
* method need not do that.
|
||||
*/
|
||||
/** Called when the lockCount goes from 0 to 1. The caller will have already
|
||||
acquire a mutex for thread safety, so this method need not do that.
|
||||
*/
|
||||
virtual void* onLockPixels(SkColorTable**) = 0;
|
||||
/** Called when the lock count goes from 1 to 0. The caller will have
|
||||
already acquire a mutex for thread safety, so this method need not do
|
||||
that.
|
||||
*/
|
||||
virtual void onUnlockPixels() = 0;
|
||||
|
||||
/** Default impl returns true */
|
||||
virtual bool onLockPixelsAreWritable() const;
|
||||
|
||||
// returns false;
|
||||
virtual bool onImplementsDecodeInto();
|
||||
// returns false;
|
||||
virtual bool onDecodeInto(int pow2, SkBitmap* bitmap);
|
||||
|
||||
/**
|
||||
* For pixelrefs that don't have access to their raw pixels, they may be
|
||||
* able to make a copy of them (e.g. if the pixels are on the GPU).
|
||||
@ -307,44 +202,32 @@ protected:
|
||||
// default impl returns NULL.
|
||||
virtual SkData* onRefEncodedData();
|
||||
|
||||
/**
|
||||
* Returns the size (in bytes) of the internally allocated memory.
|
||||
* This should be implemented in all serializable SkPixelRef derived classes.
|
||||
* SkBitmap::fPixelRefOffset + SkBitmap::getSafeSize() should never overflow this value,
|
||||
* otherwise the rendering code may attempt to read memory out of bounds.
|
||||
*
|
||||
* @return default impl returns 0.
|
||||
*/
|
||||
virtual size_t getAllocatedSizeInBytes() const;
|
||||
|
||||
/** Return the mutex associated with this pixelref. This value is assigned
|
||||
in the constructor, and cannot change during the lifetime of the object.
|
||||
*/
|
||||
SkBaseMutex* mutex() const { return fMutex; }
|
||||
|
||||
// serialization
|
||||
SkPixelRef(SkReadBuffer&, SkBaseMutex*);
|
||||
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
|
||||
SkPixelRef(SkFlattenableReadBuffer&, SkBaseMutex*);
|
||||
virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
|
||||
|
||||
// only call from constructor. Flags this to always be locked, removing
|
||||
// the need to grab the mutex and call onLockPixels/onUnlockPixels.
|
||||
// Performance tweak to avoid those calls (esp. in multi-thread use case).
|
||||
void setPreLocked(void*, size_t rowBytes, SkColorTable*);
|
||||
void setPreLocked(void* pixels, SkColorTable* ctable);
|
||||
|
||||
private:
|
||||
|
||||
SkBaseMutex* fMutex; // must remain in scope for the life of this object
|
||||
|
||||
// mostly const. fInfo.fAlpahType can be changed at runtime.
|
||||
const SkImageInfo fInfo;
|
||||
|
||||
// LockRec is only valid if we're in a locked state (isLocked())
|
||||
LockRec fRec;
|
||||
void* fPixels;
|
||||
SkColorTable* fColorTable; // we do not track ownership, subclass does
|
||||
int fLockCount;
|
||||
|
||||
mutable uint32_t fGenerationID;
|
||||
mutable bool fUniqueGenerationID;
|
||||
|
||||
SkTDArray<GenIDChangeListener*> fGenIDChangeListeners; // pointers are owned
|
||||
// SkBitmap is only a friend so that when copying, it can modify the new SkPixelRef to have the
|
||||
// same fGenerationID as the original.
|
||||
friend class SkBitmap;
|
||||
|
||||
SkString fURI;
|
||||
|
||||
@ -353,28 +236,9 @@ private:
|
||||
// only ever set in constructor, const after that
|
||||
bool fPreLocked;
|
||||
|
||||
void needsNewGenID();
|
||||
void callGenIDChangeListeners();
|
||||
|
||||
void setMutex(SkBaseMutex* mutex);
|
||||
|
||||
// When copying a bitmap to another with the same shape and config, we can safely
|
||||
// clone the pixelref generation ID too, which makes them equivalent under caching.
|
||||
friend class SkBitmap; // only for cloneGenID
|
||||
void cloneGenID(const SkPixelRef&);
|
||||
|
||||
typedef SkFlattenable INHERITED;
|
||||
};
|
||||
|
||||
class SkPixelRefFactory : public SkRefCnt {
|
||||
public:
|
||||
/**
|
||||
* Allocate a new pixelref matching the specified ImageInfo, allocating
|
||||
* the memory for the pixels. If the ImageInfo requires a ColorTable,
|
||||
* the pixelref will ref() the colortable.
|
||||
* On failure return NULL.
|
||||
*/
|
||||
virtual SkPixelRef* create(const SkImageInfo&, SkColorTable*) = 0;
|
||||
};
|
||||
|
||||
#endif
|
@ -216,10 +216,13 @@ struct SK_API SkPoint {
|
||||
* Return true if the computed length of the vector is >= the internal
|
||||
* tolerance (used to avoid dividing by tiny values).
|
||||
*/
|
||||
static bool CanNormalize(SkScalar dx, SkScalar dy) {
|
||||
// Simple enough (and performance critical sometimes) so we inline it.
|
||||
return (dx*dx + dy*dy) > (SK_ScalarNearlyZero * SK_ScalarNearlyZero);
|
||||
}
|
||||
static bool CanNormalize(SkScalar dx, SkScalar dy)
|
||||
#ifdef SK_SCALAR_IS_FLOAT
|
||||
// Simple enough (and performance critical sometimes) so we inline it.
|
||||
{ return (dx*dx + dy*dy) > (SK_ScalarNearlyZero * SK_ScalarNearlyZero); }
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
|
||||
bool canNormalize() const {
|
||||
return CanNormalize(fX, fY);
|
||||
@ -249,14 +252,6 @@ struct SK_API SkPoint {
|
||||
*/
|
||||
bool setLength(SkScalar x, SkScalar y, SkScalar length);
|
||||
|
||||
/** Same as setLength, but favoring speed over accuracy.
|
||||
*/
|
||||
bool setLengthFast(SkScalar length);
|
||||
|
||||
/** Same as setLength, but favoring speed over accuracy.
|
||||
*/
|
||||
bool setLengthFast(SkScalar x, SkScalar y, SkScalar length);
|
||||
|
||||
/** Scale the point's coordinates by scale, writing the answer into dst.
|
||||
It is legal for dst == this.
|
||||
*/
|
||||
@ -321,6 +316,7 @@ struct SK_API SkPoint {
|
||||
* Returns true if both X and Y are finite (not infinity or NaN)
|
||||
*/
|
||||
bool isFinite() const {
|
||||
#ifdef SK_SCALAR_IS_FLOAT
|
||||
SkScalar accum = 0;
|
||||
accum *= fX;
|
||||
accum *= fY;
|
||||
@ -331,6 +327,12 @@ struct SK_API SkPoint {
|
||||
// value==value will be true iff value is not NaN
|
||||
// TODO: is it faster to say !accum or accum==accum?
|
||||
return accum == accum;
|
||||
#else
|
||||
// use bit-or for speed, since we don't care about short-circuting the
|
||||
// tests, and we expect the common case will be that we need to check all.
|
||||
int isNaN = (SK_FixedNaN == fX) | (SK_FixedNaN == fX));
|
||||
return !isNaN;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@ -351,7 +353,7 @@ struct SK_API SkPoint {
|
||||
/** Return true if this point and the given point are far enough apart
|
||||
such that a vector between them would be non-degenerate.
|
||||
|
||||
WARNING: Unlike the explicit tolerance version,
|
||||
WARNING: Unlike the deprecated version of equalsWithinTolerance(),
|
||||
this method does not use componentwise comparison. Instead, it
|
||||
uses a comparison designed to match judgments elsewhere regarding
|
||||
degeneracy ("points A and B are so close that the vector between them
|
||||
@ -361,7 +363,10 @@ struct SK_API SkPoint {
|
||||
return !CanNormalize(fX - p.fX, fY - p.fY);
|
||||
}
|
||||
|
||||
/** WARNING: There is no guarantee that the result will reflect judgments
|
||||
/** DEPRECATED: Return true if this and the given point are componentwise
|
||||
within tolerance "tol".
|
||||
|
||||
WARNING: There is no guarantee that the result will reflect judgments
|
||||
elsewhere regarding degeneracy ("points A and B are so close that the
|
||||
vector between them is essentially zero").
|
||||
*/
|
||||
@ -411,13 +416,13 @@ struct SK_API SkPoint {
|
||||
/** Returns the dot product of a and b, treating them as 2D vectors
|
||||
*/
|
||||
static SkScalar DotProduct(const SkPoint& a, const SkPoint& b) {
|
||||
return a.fX * b.fX + a.fY * b.fY;
|
||||
return SkScalarMul(a.fX, b.fX) + SkScalarMul(a.fY, b.fY);
|
||||
}
|
||||
|
||||
/** Returns the cross product of a and b, treating them as 2D vectors
|
||||
*/
|
||||
static SkScalar CrossProduct(const SkPoint& a, const SkPoint& b) {
|
||||
return a.fX * b.fY - a.fY * b.fX;
|
||||
return SkScalarMul(a.fX, b.fY) - SkScalarMul(a.fY, b.fX);
|
||||
}
|
||||
|
||||
SkScalar cross(const SkPoint& vec) const {
|
||||
@ -435,7 +440,7 @@ struct SK_API SkPoint {
|
||||
SkScalar distanceToSqd(const SkPoint& pt) const {
|
||||
SkScalar dx = fX - pt.fX;
|
||||
SkScalar dy = fY - pt.fY;
|
||||
return dx * dx + dy * dy;
|
||||
return SkScalarMul(dx, dx) + SkScalarMul(dy, dy);
|
||||
}
|
||||
|
||||
/**
|
363
gfx/skia/include/core/SkPostConfig.h
Normal file
363
gfx/skia/include/core/SkPostConfig.h
Normal file
@ -0,0 +1,363 @@
|
||||
|
||||
/*
|
||||
* 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 SkPostConfig_DEFINED
|
||||
#define SkPostConfig_DEFINED
|
||||
|
||||
#if defined(SK_BUILD_FOR_WIN32) || defined(SK_BUILD_FOR_WINCE)
|
||||
#define SK_BUILD_FOR_WIN
|
||||
#endif
|
||||
|
||||
#if defined(SK_DEBUG) && defined(SK_RELEASE)
|
||||
#error "cannot define both SK_DEBUG and SK_RELEASE"
|
||||
#elif !defined(SK_DEBUG) && !defined(SK_RELEASE)
|
||||
#error "must define either SK_DEBUG or SK_RELEASE"
|
||||
#endif
|
||||
|
||||
#if defined SK_SUPPORT_UNITTEST && !defined(SK_DEBUG)
|
||||
#error "can't have unittests without debug"
|
||||
#endif
|
||||
|
||||
#if defined(SK_SCALAR_IS_FIXED) && defined(SK_SCALAR_IS_FLOAT)
|
||||
#error "cannot define both SK_SCALAR_IS_FIXED and SK_SCALAR_IS_FLOAT"
|
||||
#elif !defined(SK_SCALAR_IS_FIXED) && !defined(SK_SCALAR_IS_FLOAT)
|
||||
#define SK_SCALAR_IS_FLOAT
|
||||
#endif
|
||||
|
||||
#if defined(SK_MSCALAR_IS_DOUBLE) && defined(SK_MSCALAR_IS_FLOAT)
|
||||
#error "cannot define both SK_MSCALAR_IS_DOUBLE and SK_MSCALAR_IS_FLOAT"
|
||||
#elif !defined(SK_MSCALAR_IS_DOUBLE) && !defined(SK_MSCALAR_IS_FLOAT)
|
||||
// default is double, as that is faster given our impl uses doubles
|
||||
// for intermediate calculations.
|
||||
#define SK_MSCALAR_IS_DOUBLE
|
||||
#endif
|
||||
|
||||
#if defined(SK_CPU_LENDIAN) && defined(SK_CPU_BENDIAN)
|
||||
#error "cannot define both SK_CPU_LENDIAN and SK_CPU_BENDIAN"
|
||||
#elif !defined(SK_CPU_LENDIAN) && !defined(SK_CPU_BENDIAN)
|
||||
#error "must define either SK_CPU_LENDIAN or SK_CPU_BENDIAN"
|
||||
#endif
|
||||
|
||||
// ensure the port has defined all of these, or none of them
|
||||
#ifdef SK_A32_SHIFT
|
||||
#if !defined(SK_R32_SHIFT) || !defined(SK_G32_SHIFT) || !defined(SK_B32_SHIFT)
|
||||
#error "all or none of the 32bit SHIFT amounts must be defined"
|
||||
#endif
|
||||
#else
|
||||
#if defined(SK_R32_SHIFT) || defined(SK_G32_SHIFT) || defined(SK_B32_SHIFT)
|
||||
#error "all or none of the 32bit SHIFT amounts must be defined"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(SK_HAS_COMPILER_FEATURE)
|
||||
#if defined(__has_feature)
|
||||
#define SK_HAS_COMPILER_FEATURE(x) __has_feature(x)
|
||||
#else
|
||||
#define SK_HAS_COMPILER_FEATURE(x) 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(SK_SUPPORT_GPU)
|
||||
#define SK_SUPPORT_GPU 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The clang static analyzer likes to know that when the program is not
|
||||
* expected to continue (crash, assertion failure, etc). It will notice that
|
||||
* some combination of parameters lead to a function call that does not return.
|
||||
* It can then make appropriate assumptions about the parameters in code
|
||||
* executed only if the non-returning function was *not* called.
|
||||
*/
|
||||
#if !defined(SkNO_RETURN_HINT)
|
||||
#if SK_HAS_COMPILER_FEATURE(attribute_analyzer_noreturn)
|
||||
static inline void SkNO_RETURN_HINT() __attribute__((analyzer_noreturn));
|
||||
static inline void SkNO_RETURN_HINT() {}
|
||||
#else
|
||||
#define SkNO_RETURN_HINT() do {} while (false)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(SK_ZLIB_INCLUDE) && defined(SK_SYSTEM_ZLIB)
|
||||
#error "cannot define both SK_ZLIB_INCLUDE and SK_SYSTEM_ZLIB"
|
||||
#elif defined(SK_ZLIB_INCLUDE) || defined(SK_SYSTEM_ZLIB)
|
||||
#define SK_HAS_ZLIB
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SkNEW
|
||||
#define SkNEW(type_name) (new type_name)
|
||||
#define SkNEW_ARGS(type_name, args) (new type_name args)
|
||||
#define SkNEW_ARRAY(type_name, count) (new type_name[(count)])
|
||||
#define SkNEW_PLACEMENT(buf, type_name) (new (buf) type_name)
|
||||
#define SkNEW_PLACEMENT_ARGS(buf, type_name, args) \
|
||||
(new (buf) type_name args)
|
||||
#define SkDELETE(obj) (delete (obj))
|
||||
#define SkDELETE_ARRAY(array) (delete[] (array))
|
||||
#endif
|
||||
|
||||
#ifndef SK_CRASH
|
||||
#if 1 // set to 0 for infinite loop, which can help connecting gdb
|
||||
#define SK_CRASH() do { SkNO_RETURN_HINT(); *(int *)(uintptr_t)0xbbadbeef = 0; } while (false)
|
||||
#else
|
||||
#define SK_CRASH() do { SkNO_RETURN_HINT(); } while (true)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// SK_ENABLE_INST_COUNT defaults to 1 in DEBUG and 0 in RELEASE
|
||||
#ifndef SK_ENABLE_INST_COUNT
|
||||
#ifdef SK_DEBUG
|
||||
#define SK_ENABLE_INST_COUNT 1
|
||||
#else
|
||||
#define SK_ENABLE_INST_COUNT 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(SK_SOFTWARE_FLOAT) && defined(SK_SCALAR_IS_FLOAT)
|
||||
// if this is defined, we convert floats to 2scompliment ints for compares
|
||||
#ifndef SK_SCALAR_SLOW_COMPARES
|
||||
#define SK_SCALAR_SLOW_COMPARES
|
||||
#endif
|
||||
#ifndef SK_USE_FLOATBITS
|
||||
#define SK_USE_FLOATBITS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef SK_BUILD_FOR_WIN
|
||||
// we want lean_and_mean when we include windows.h
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_IS_MEAN_WAS_LOCALLY_DEFINED
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef WIN32_IS_MEAN_WAS_LOCALLY_DEFINED
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#ifndef SK_DEBUGBREAK
|
||||
#define SK_DEBUGBREAK(cond) do { if (!(cond)) { SkNO_RETURN_HINT(); __debugbreak(); }} while (false)
|
||||
#endif
|
||||
|
||||
#ifndef SK_A32_SHIFT
|
||||
#define SK_A32_SHIFT 24
|
||||
#define SK_R32_SHIFT 16
|
||||
#define SK_G32_SHIFT 8
|
||||
#define SK_B32_SHIFT 0
|
||||
#endif
|
||||
|
||||
#else
|
||||
#ifdef SK_DEBUG
|
||||
#include <stdio.h>
|
||||
#ifndef SK_DEBUGBREAK
|
||||
#define SK_DEBUGBREAK(cond) do { if (cond) break; \
|
||||
SkDebugf("%s:%d: failed assertion \"%s\"\n", \
|
||||
__FILE__, __LINE__, #cond); SK_CRASH(); } while (false)
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We check to see if the SHIFT value has already been defined.
|
||||
* if not, we define it ourself to some default values. We default to OpenGL
|
||||
* order (in memory: r,g,b,a)
|
||||
*/
|
||||
#ifndef SK_A32_SHIFT
|
||||
#ifdef SK_CPU_BENDIAN
|
||||
#define SK_R32_SHIFT 24
|
||||
#define SK_G32_SHIFT 16
|
||||
#define SK_B32_SHIFT 8
|
||||
#define SK_A32_SHIFT 0
|
||||
#else
|
||||
#define SK_R32_SHIFT 0
|
||||
#define SK_G32_SHIFT 8
|
||||
#define SK_B32_SHIFT 16
|
||||
#define SK_A32_SHIFT 24
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* SK_PMCOLOR_BYTE_ORDER can be used to query the byte order of SkPMColor at compile time. The
|
||||
* relationship between the byte order and shift values depends on machine endianness. If the shift
|
||||
* order is R=0, G=8, B=16, A=24 then ((char*)&pmcolor)[0] will produce the R channel on a little
|
||||
* endian machine and the A channel on a big endian machine. Thus, given those shifts values,
|
||||
* SK_PMCOLOR_BYTE_ORDER(R,G,B,A) will be true on a little endian machine and
|
||||
* SK_PMCOLOR_BYTE_ORDER(A,B,G,R) will be true on a big endian machine.
|
||||
*/
|
||||
#ifdef SK_CPU_BENDIAN
|
||||
#define SK_PMCOLOR_BYTE_ORDER(C0, C1, C2, C3) \
|
||||
(SK_ ## C3 ## 32_SHIFT == 0 && \
|
||||
SK_ ## C2 ## 32_SHIFT == 8 && \
|
||||
SK_ ## C1 ## 32_SHIFT == 16 && \
|
||||
SK_ ## C0 ## 32_SHIFT == 24)
|
||||
#else
|
||||
#define SK_PMCOLOR_BYTE_ORDER(C0, C1, C2, C3) \
|
||||
(SK_ ## C0 ## 32_SHIFT == 0 && \
|
||||
SK_ ## C1 ## 32_SHIFT == 8 && \
|
||||
SK_ ## C2 ## 32_SHIFT == 16 && \
|
||||
SK_ ## C3 ## 32_SHIFT == 24)
|
||||
#endif
|
||||
|
||||
// stdlib macros
|
||||
|
||||
#if 0
|
||||
#if !defined(strlen) && defined(SK_DEBUG)
|
||||
extern size_t sk_strlen(const char*);
|
||||
#define strlen(s) sk_strlen(s)
|
||||
#endif
|
||||
#ifndef sk_strcpy
|
||||
#define sk_strcpy(dst, src) strcpy(dst, src)
|
||||
#endif
|
||||
#ifndef sk_strchr
|
||||
#define sk_strchr(s, c) strchr(s, c)
|
||||
#endif
|
||||
#ifndef sk_strrchr
|
||||
#define sk_strrchr(s, c) strrchr(s, c)
|
||||
#endif
|
||||
#ifndef sk_strcmp
|
||||
#define sk_strcmp(s, t) strcmp(s, t)
|
||||
#endif
|
||||
#ifndef sk_strncmp
|
||||
#define sk_strncmp(s, t, n) strncmp(s, t, n)
|
||||
#endif
|
||||
#ifndef sk_memcpy
|
||||
#define sk_memcpy(dst, src, n) memcpy(dst, src, n)
|
||||
#endif
|
||||
#ifndef memmove
|
||||
#define memmove(dst, src, n) memmove(dst, src, n)
|
||||
#endif
|
||||
#ifndef sk_memset
|
||||
#define sk_memset(dst, val, n) memset(dst, val, n)
|
||||
#endif
|
||||
#ifndef sk_memcmp
|
||||
#define sk_memcmp(s, t, n) memcmp(s, t, n)
|
||||
#endif
|
||||
|
||||
#define sk_strequal(s, t) (!sk_strcmp(s, t))
|
||||
#define sk_strnequal(s, t, n) (!sk_strncmp(s, t, n))
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(SK_BUILD_FOR_WIN32) || defined(SK_BUILD_FOR_MAC)
|
||||
#ifndef SkLONGLONG
|
||||
#ifdef SK_BUILD_FOR_WIN32
|
||||
#define SkLONGLONG __int64
|
||||
#else
|
||||
#define SkLONGLONG long long
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef SK_BUILD_FOR_WINCE
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
#define _CMNINTRIN_DECLARE_ONLY
|
||||
#include "cmnintrin.h"
|
||||
#endif
|
||||
|
||||
#if defined SK_DEBUG && defined SK_BUILD_FOR_WIN32
|
||||
//#define _CRTDBG_MAP_ALLOC
|
||||
#ifdef free
|
||||
#undef free
|
||||
#endif
|
||||
#include <crtdbg.h>
|
||||
#undef free
|
||||
|
||||
#ifdef SK_DEBUGx
|
||||
#if defined(SK_SIMULATE_FAILED_MALLOC) && defined(__cplusplus)
|
||||
void * operator new(
|
||||
size_t cb,
|
||||
int nBlockUse,
|
||||
const char * szFileName,
|
||||
int nLine,
|
||||
int foo
|
||||
);
|
||||
void * operator new[](
|
||||
size_t cb,
|
||||
int nBlockUse,
|
||||
const char * szFileName,
|
||||
int nLine,
|
||||
int foo
|
||||
);
|
||||
void operator delete(
|
||||
void *pUserData,
|
||||
int, const char*, int, int
|
||||
);
|
||||
void operator delete(
|
||||
void *pUserData
|
||||
);
|
||||
void operator delete[]( void * p );
|
||||
#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__, 0)
|
||||
#else
|
||||
#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__)
|
||||
#endif
|
||||
#define new DEBUG_CLIENTBLOCK
|
||||
#else
|
||||
#define DEBUG_CLIENTBLOCK
|
||||
#endif // _DEBUG
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SK_OVERRIDE
|
||||
#if defined(_MSC_VER)
|
||||
#define SK_OVERRIDE override
|
||||
#elif defined(__clang__) && !defined(SK_BUILD_FOR_IOS)
|
||||
#if __has_feature(cxx_override_control)
|
||||
// Some documentation suggests we should be using __attribute__((override)),
|
||||
// but it doesn't work.
|
||||
#define SK_OVERRIDE override
|
||||
#elif defined(__has_extension)
|
||||
#if __has_extension(cxx_override_control)
|
||||
#define SK_OVERRIDE override
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#ifndef SK_OVERRIDE
|
||||
#define SK_OVERRIDE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SK_PRINTF_LIKE
|
||||
#if defined(__clang__) || defined(__GNUC__)
|
||||
#define SK_PRINTF_LIKE(A, B) __attribute__((format(printf, (A), (B))))
|
||||
#else
|
||||
#define SK_PRINTF_LIKE(A, B)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SK_SIZE_T_SPECIFIER
|
||||
#if defined(_MSC_VER)
|
||||
#define SK_SIZE_T_SPECIFIER "%Iu"
|
||||
#else
|
||||
#define SK_SIZE_T_SPECIFIER "%zu"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
|
||||
#define SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 1
|
||||
#endif
|
@ -14,13 +14,6 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
// Allows embedders that want to disable macros that take arguments to just
|
||||
// define that symbol to be one of these
|
||||
//
|
||||
#define SK_NOTHING_ARG1(arg1)
|
||||
#define SK_NOTHING_ARG2(arg1, arg2)
|
||||
#define SK_NOTHING_ARG3(arg1, arg2, arg3)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(SK_BUILD_FOR_ANDROID) && !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_PALM) && !defined(SK_BUILD_FOR_WINCE) && !defined(SK_BUILD_FOR_WIN32) && !defined(SK_BUILD_FOR_UNIX) && !defined(SK_BUILD_FOR_MAC) && !defined(SK_BUILD_FOR_SDL) && !defined(SK_BUILD_FOR_BREW) && !defined(SK_BUILD_FOR_NACL)
|
||||
@ -60,6 +53,13 @@
|
||||
#define SK_BUILD_FOR_ANDROID
|
||||
#endif
|
||||
|
||||
|
||||
// USE_CHROMIUM_SKIA is defined when building Skia for the Chromium
|
||||
// browser.
|
||||
#if defined(USE_CHROMIUM_SKIA)
|
||||
#define SK_BUILD_FOR_CHROMIUM
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(SK_DEBUG) && !defined(SK_RELEASE)
|
||||
@ -77,6 +77,7 @@
|
||||
#if !defined(SK_WARN_UNUSED_RESULT)
|
||||
#define SK_WARN_UNUSED_RESULT
|
||||
#endif
|
||||
#include "sk_stdint.h"
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -91,6 +92,12 @@
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(SK_SCALAR_IS_FLOAT) && !defined(SK_SCALAR_IS_FIXED)
|
||||
#define SK_SCALAR_IS_FLOAT
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(SK_CPU_BENDIAN) && !defined(SK_CPU_LENDIAN)
|
||||
#if defined (__ppc__) || defined(__PPC__) || defined(__ppc64__) \
|
||||
|| defined(__PPC64__)
|
||||
@ -102,6 +109,17 @@
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SK_MMAP_SUPPORT
|
||||
#ifdef SK_BUILD_FOR_WIN32
|
||||
// by default, if we're windows, we assume we don't have mmap
|
||||
#define SK_MMAP_SUPPORT 0
|
||||
#else
|
||||
#define SK_MMAP_SUPPORT 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* SK_CPU_SSE_LEVEL
|
||||
*
|
||||
@ -127,12 +145,10 @@
|
||||
|
||||
// Are we in VisualStudio?
|
||||
#ifndef SK_CPU_SSE_LEVEL
|
||||
#if defined (_M_IX86_FP)
|
||||
#if _M_IX86_FP == 1
|
||||
#define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE1
|
||||
#elif _M_IX86_FP >= 2
|
||||
#define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE2
|
||||
#endif
|
||||
#if _M_IX86_FP == 1
|
||||
#define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE1
|
||||
#elif _M_IX86_FP >= 2
|
||||
#define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE2
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -144,12 +160,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Android x86 NDK ABI requires SSE3 support
|
||||
#if defined(SK_BUILD_FOR_ANDROID)
|
||||
#undef SK_CPU_SSE_LEVEL
|
||||
#define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE3
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// ARM defines
|
||||
|
||||
@ -186,6 +196,16 @@
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* THUMB is the only known config where we avoid small branches in
|
||||
* favor of more complex math.
|
||||
*/
|
||||
#if !(defined(__arm__) && defined(__thumb__))
|
||||
#define SK_CPU_HAS_CONDITIONAL_INSTR
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(SKIA_IMPLEMENTATION)
|
||||
#define SKIA_IMPLEMENTATION 0
|
||||
#endif
|
@ -12,7 +12,6 @@
|
||||
#include "SkPoint.h"
|
||||
|
||||
class SkPath;
|
||||
class SkMatrix;
|
||||
|
||||
// Path forward:
|
||||
// core work
|
||||
@ -26,7 +25,7 @@ class SkMatrix;
|
||||
// use growToInclude to fit skp round rects & generate stats (RRs vs. real paths)
|
||||
// check on # of rectorus's the RRs could handle
|
||||
// rendering work
|
||||
// add entry points (clipRRect, drawRRect) - plumb down to SkBaseDevice
|
||||
// add entry points (clipRRect, drawRRect) - plumb down to SkDevice
|
||||
// update SkPath.addRRect() to take an SkRRect - only use quads
|
||||
// -- alternatively add addRRectToPath here
|
||||
// add GM and bench
|
||||
@ -199,6 +198,30 @@ public:
|
||||
b.fRadii[0].asScalars(), 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if (p.fX,p.fY) is inside the RR, and the RR
|
||||
* is not empty.
|
||||
*
|
||||
* Contains treats the left and top differently from the right and bottom.
|
||||
* The left and top coordinates of the RR are themselves considered
|
||||
* to be inside, while the right and bottom are not. All the points on the
|
||||
* edges of the corners are considered to be inside.
|
||||
*/
|
||||
bool contains(const SkPoint& p) const {
|
||||
return contains(p.fX, p.fY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if (x,y) is inside the RR, and the RR
|
||||
* is not empty.
|
||||
*
|
||||
* Contains treats the left and top differently from the right and bottom.
|
||||
* The left and top coordinates of the RR are themselves considered
|
||||
* to be inside, while the right and bottom are not. All the points on the
|
||||
* edges of the corners are considered to be inside.
|
||||
*/
|
||||
bool contains(SkScalar x, SkScalar y) const;
|
||||
|
||||
/**
|
||||
* Call inset on the bounds, and adjust the radii to reflect what happens
|
||||
* in stroking: If the corner is sharp (no curvature), leave it alone,
|
||||
@ -228,12 +251,6 @@ public:
|
||||
this->inset(-dx, -dy, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if 'rect' is wholy inside the RR, and both
|
||||
* are not empty.
|
||||
*/
|
||||
bool contains(const SkRect& rect) const;
|
||||
|
||||
SkDEBUGCODE(void validate() const;)
|
||||
|
||||
enum {
|
||||
@ -245,31 +262,14 @@ public:
|
||||
* write kSizeInMemory bytes, and that value is guaranteed to always be
|
||||
* a multiple of 4. Return kSizeInMemory.
|
||||
*/
|
||||
size_t writeToMemory(void* buffer) const;
|
||||
uint32_t writeToMemory(void* buffer) const;
|
||||
|
||||
/**
|
||||
* Reads the rrect from the specified buffer
|
||||
*
|
||||
* If the specified buffer is large enough, this will read kSizeInMemory bytes,
|
||||
* and that value is guaranteed to always be a multiple of 4.
|
||||
*
|
||||
* @param buffer Memory to read from
|
||||
* @param length Amount of memory available in the buffer
|
||||
* @return number of bytes read (must be a multiple of 4) or
|
||||
* 0 if there was not enough memory available
|
||||
* Read the rrect from the specified buffer. This is guaranteed to always
|
||||
* read kSizeInMemory bytes, and that value is guaranteed to always be
|
||||
* a multiple of 4. Return kSizeInMemory.
|
||||
*/
|
||||
size_t readFromMemory(const void* buffer, size_t length);
|
||||
|
||||
/**
|
||||
* Transform by the specified matrix, and put the result in dst.
|
||||
*
|
||||
* @param matrix SkMatrix specifying the transform. Must only contain
|
||||
* scale and/or translate, or this call will fail.
|
||||
* @param dst SkRRect to store the result. It is an error to use this,
|
||||
* which would make this function no longer const.
|
||||
* @return true on success, false on failure. If false, dst is unmodified.
|
||||
*/
|
||||
bool transform(const SkMatrix& matrix, SkRRect* dst) const;
|
||||
uint32_t readFromMemory(const void* buffer);
|
||||
|
||||
private:
|
||||
SkRect fRect;
|
||||
@ -280,7 +280,6 @@ private:
|
||||
// uninitialized data
|
||||
|
||||
void computeType() const;
|
||||
bool checkCornerContainment(SkScalar x, SkScalar y) const;
|
||||
|
||||
// to access fRadii directly
|
||||
friend class SkPath;
|
@ -30,10 +30,8 @@ public:
|
||||
const SkIRect* clipBounds, SkMaskFilter* filter,
|
||||
SkMask* mask, SkMask::CreateMode mode) const;
|
||||
|
||||
SK_DEFINE_FLATTENABLE_TYPE(SkRasterizer)
|
||||
|
||||
protected:
|
||||
SkRasterizer(SkReadBuffer& buffer) : INHERITED(buffer) {}
|
||||
SkRasterizer(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
|
||||
|
||||
virtual bool onRasterize(const SkPath& path, const SkMatrix& matrix,
|
||||
const SkIRect* clipBounds,
|
@ -106,20 +106,27 @@ public:
|
||||
int32_t readS32() { return this->readInt(); }
|
||||
uint32_t readU32() { return this->readInt(); }
|
||||
|
||||
bool readPath(SkPath* path) {
|
||||
return readObjectFromMemory(path);
|
||||
void readPath(SkPath* path) {
|
||||
size_t size = path->readFromMemory(this->peek());
|
||||
SkASSERT(SkAlign4(size) == size);
|
||||
(void)this->skip(size);
|
||||
}
|
||||
|
||||
bool readMatrix(SkMatrix* matrix) {
|
||||
return readObjectFromMemory(matrix);
|
||||
void readMatrix(SkMatrix* matrix) {
|
||||
size_t size = matrix->readFromMemory(this->peek());
|
||||
SkASSERT(SkAlign4(size) == size);
|
||||
(void)this->skip(size);
|
||||
}
|
||||
|
||||
bool readRRect(SkRRect* rrect) {
|
||||
return readObjectFromMemory(rrect);
|
||||
SkRRect* readRRect(SkRRect* rrect) {
|
||||
rrect->readFromMemory(this->skip(SkRRect::kSizeInMemory));
|
||||
return rrect;
|
||||
}
|
||||
|
||||
bool readRegion(SkRegion* rgn) {
|
||||
return readObjectFromMemory(rgn);
|
||||
void readRegion(SkRegion* rgn) {
|
||||
size_t size = rgn->readFromMemory(this->peek());
|
||||
SkASSERT(SkAlign4(size) == size);
|
||||
(void)this->skip(size);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -136,15 +143,6 @@ public:
|
||||
size_t readIntoString(SkString* copy);
|
||||
|
||||
private:
|
||||
template <typename T> bool readObjectFromMemory(T* obj) {
|
||||
size_t size = obj->readFromMemory(this->peek(), this->available());
|
||||
// If readFromMemory() fails (which means that available() was too small), it returns 0
|
||||
bool success = (size > 0) && (size <= this->available()) && (SkAlign4(size) == size);
|
||||
// In case of failure, we want to skip to the end
|
||||
(void)this->skip(success ? size : this->available());
|
||||
return success;
|
||||
}
|
||||
|
||||
// these are always 4-byte aligned
|
||||
const char* fCurr; // current position within buffer
|
||||
const char* fStop; // end of buffer
|
@ -26,12 +26,6 @@ struct SK_API SkIRect {
|
||||
return r;
|
||||
}
|
||||
|
||||
static SkIRect SK_WARN_UNUSED_RESULT MakeLargest() {
|
||||
SkIRect r;
|
||||
r.setLargest();
|
||||
return r;
|
||||
}
|
||||
|
||||
static SkIRect SK_WARN_UNUSED_RESULT MakeWH(int32_t w, int32_t h) {
|
||||
SkIRect r;
|
||||
r.set(0, 0, w, h);
|
||||
@ -100,11 +94,6 @@ struct SK_API SkIRect {
|
||||
*/
|
||||
bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
|
||||
|
||||
bool isLargest() const { return SK_MinS32 == fLeft &&
|
||||
SK_MinS32 == fTop &&
|
||||
SK_MaxS32 == fRight &&
|
||||
SK_MaxS32 == fBottom; }
|
||||
|
||||
friend bool operator==(const SkIRect& a, const SkIRect& b) {
|
||||
return !memcmp(&a, &b, sizeof(a));
|
||||
}
|
||||
@ -371,12 +360,6 @@ struct SK_API SkRect {
|
||||
return r;
|
||||
}
|
||||
|
||||
static SkRect SK_WARN_UNUSED_RESULT MakeLargest() {
|
||||
SkRect r;
|
||||
r.setLargest();
|
||||
return r;
|
||||
}
|
||||
|
||||
static SkRect SK_WARN_UNUSED_RESULT MakeWH(SkScalar w, SkScalar h) {
|
||||
SkRect r;
|
||||
r.set(0, 0, w, h);
|
||||
@ -401,7 +384,7 @@ struct SK_API SkRect {
|
||||
return r;
|
||||
}
|
||||
|
||||
SK_ATTR_DEPRECATED("use Make()")
|
||||
// DEPRECATED: call Make(r)
|
||||
static SkRect SK_WARN_UNUSED_RESULT MakeFromIRect(const SkIRect& irect) {
|
||||
SkRect r;
|
||||
r.set(SkIntToScalar(irect.fLeft),
|
||||
@ -425,17 +408,13 @@ struct SK_API SkRect {
|
||||
*/
|
||||
bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
|
||||
|
||||
bool isLargest() const { return SK_ScalarMin == fLeft &&
|
||||
SK_ScalarMin == fTop &&
|
||||
SK_ScalarMax == fRight &&
|
||||
SK_ScalarMax == fBottom; }
|
||||
|
||||
/**
|
||||
* Returns true iff all values in the rect are finite. If any are
|
||||
* infinite or NaN (or SK_FixedNaN when SkScalar is fixed) then this
|
||||
* returns false.
|
||||
*/
|
||||
bool isFinite() const {
|
||||
#ifdef SK_SCALAR_IS_FLOAT
|
||||
float accum = 0;
|
||||
accum *= fLeft;
|
||||
accum *= fTop;
|
||||
@ -448,6 +427,13 @@ struct SK_API SkRect {
|
||||
// value==value will be true iff value is not NaN
|
||||
// TODO: is it faster to say !accum or accum==accum?
|
||||
return accum == accum;
|
||||
#else
|
||||
// use bit-or for speed, since we don't care about short-circuting the
|
||||
// tests, and we expect the common case will be that we need to check all.
|
||||
int isNaN = (SK_FixedNaN == fLeft) | (SK_FixedNaN == fTop) |
|
||||
(SK_FixedNaN == fRight) | (SK_FixedNaN == fBottom);
|
||||
return !isNaN;
|
||||
#endif
|
||||
}
|
||||
|
||||
SkScalar x() const { return fLeft; }
|
||||
@ -469,9 +455,8 @@ struct SK_API SkRect {
|
||||
return !SkScalarsEqual((SkScalar*)&a, (SkScalar*)&b, 4);
|
||||
}
|
||||
|
||||
/** return the 4 points that enclose the rectangle (top-left, top-right, bottom-right,
|
||||
bottom-left). TODO: Consider adding param to control whether quad is CW or CCW.
|
||||
*/
|
||||
/** return the 4 points that enclose the rectangle
|
||||
*/
|
||||
void toQuad(SkPoint quad[4]) const;
|
||||
|
||||
/** Set this rectangle to the empty rectangle (0,0,0,0)
|
||||
@ -625,7 +610,6 @@ struct SK_API SkRect {
|
||||
If either rectangle is empty, do nothing and return false.
|
||||
*/
|
||||
bool intersect(const SkRect& r);
|
||||
bool intersect2(const SkRect& r);
|
||||
|
||||
/** If this rectangle intersects the rectangle specified by left, top, right, bottom,
|
||||
return true and set this rectangle to that intersection, otherwise return false
|
||||
@ -695,19 +679,32 @@ struct SK_API SkRect {
|
||||
fBottom = SkMaxScalar(y, fBottom);
|
||||
}
|
||||
|
||||
/** Bulk version of growToInclude */
|
||||
void growToInclude(const SkPoint pts[], int count) {
|
||||
this->growToInclude(pts, sizeof(SkPoint), count);
|
||||
/**
|
||||
* Returns true if (p.fX,p.fY) is inside the rectangle, and the rectangle
|
||||
* is not empty.
|
||||
*
|
||||
* Contains treats the left and top differently from the right and bottom.
|
||||
* The left and top coordinates of the rectangle are themselves considered
|
||||
* to be inside, while the right and bottom are not. Thus for the rectangle
|
||||
* {0, 0, 5, 10}, (0,0) is contained, but (0,10), (5,0) and (5,10) are not.
|
||||
*/
|
||||
bool contains(const SkPoint& p) const {
|
||||
return !this->isEmpty() &&
|
||||
fLeft <= p.fX && p.fX < fRight && fTop <= p.fY && p.fY < fBottom;
|
||||
}
|
||||
|
||||
/** Bulk version of growToInclude with stride. */
|
||||
void growToInclude(const SkPoint pts[], size_t stride, int count) {
|
||||
SkASSERT(count >= 0);
|
||||
SkASSERT(stride >= sizeof(SkPoint));
|
||||
const SkPoint* end = (const SkPoint*)((intptr_t)pts + count * stride);
|
||||
for (; pts < end; pts = (const SkPoint*)((intptr_t)pts + stride)) {
|
||||
this->growToInclude(pts->fX, pts->fY);
|
||||
}
|
||||
/**
|
||||
* Returns true if (x,y) is inside the rectangle, and the rectangle
|
||||
* is not empty.
|
||||
*
|
||||
* Contains treats the left and top differently from the right and bottom.
|
||||
* The left and top coordinates of the rectangle are themselves considered
|
||||
* to be inside, while the right and bottom are not. Thus for the rectangle
|
||||
* {0, 0, 5, 10}, (0,0) is contained, but (0,10), (5,0) and (5,10) are not.
|
||||
*/
|
||||
bool contains(SkScalar x, SkScalar y) const {
|
||||
return !this->isEmpty() &&
|
||||
fLeft <= x && x < fRight && fTop <= y && y < fBottom;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -715,7 +712,6 @@ struct SK_API SkRect {
|
||||
* not empty.
|
||||
*/
|
||||
bool contains(const SkRect& r) const {
|
||||
// todo: can we eliminate the this->isEmpty check?
|
||||
return !r.isEmpty() && !this->isEmpty() &&
|
||||
fLeft <= r.fLeft && fTop <= r.fTop &&
|
||||
fRight >= r.fRight && fBottom >= r.fBottom;
|
||||
@ -723,7 +719,7 @@ struct SK_API SkRect {
|
||||
|
||||
/**
|
||||
* Set the dst rectangle by rounding this rectangle's coordinates to their
|
||||
* nearest integer values using SkScalarRoundToInt.
|
||||
* nearest integer values using SkScalarRound.
|
||||
*/
|
||||
void round(SkIRect* dst) const {
|
||||
SkASSERT(dst);
|
||||
@ -765,15 +761,6 @@ struct SK_API SkRect {
|
||||
SkScalarFloorToInt(fRight), SkScalarFloorToInt(fBottom));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new SkIRect which is contains the rounded coordinates of this
|
||||
* rect using SkScalarRoundToInt.
|
||||
*/
|
||||
SkIRect round() const {
|
||||
SkIRect ir;
|
||||
this->round(&ir);
|
||||
return ir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Swap top/bottom or left/right if there are flipped (i.e. if width()
|
@ -10,14 +10,13 @@
|
||||
#ifndef SkRefCnt_DEFINED
|
||||
#define SkRefCnt_DEFINED
|
||||
|
||||
#include "SkDynamicAnnotations.h"
|
||||
#include "SkThread.h"
|
||||
#include "SkInstCnt.h"
|
||||
#include "SkTemplates.h"
|
||||
|
||||
/** \class SkRefCntBase
|
||||
/** \class SkRefCnt
|
||||
|
||||
SkRefCntBase is the base class for objects that may be shared by multiple
|
||||
SkRefCnt is the base class for objects that may be shared by multiple
|
||||
objects. When an existing owner wants to share a reference, it calls ref().
|
||||
When an owner wants to release its reference, it calls unref(). When the
|
||||
shared object's reference count goes to zero as the result of an unref()
|
||||
@ -25,41 +24,27 @@
|
||||
destructor to be called explicitly (or via the object going out of scope on
|
||||
the stack or calling delete) if getRefCnt() > 1.
|
||||
*/
|
||||
class SK_API SkRefCntBase : public SkNoncopyable {
|
||||
class SK_API SkRefCnt : SkNoncopyable {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT_ROOT(SkRefCntBase)
|
||||
SK_DECLARE_INST_COUNT_ROOT(SkRefCnt)
|
||||
|
||||
/** Default construct, initializing the reference count to 1.
|
||||
*/
|
||||
SkRefCntBase() : fRefCnt(1) {}
|
||||
SkRefCnt() : fRefCnt(1) {}
|
||||
|
||||
/** Destruct, asserting that the reference count is 1.
|
||||
*/
|
||||
virtual ~SkRefCntBase() {
|
||||
virtual ~SkRefCnt() {
|
||||
#ifdef SK_DEBUG
|
||||
SkASSERT(fRefCnt == 1);
|
||||
fRefCnt = 0; // illegal value, to catch us if we reuse after delete
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Return the reference count. Use only for debugging. */
|
||||
/** Return the reference count.
|
||||
*/
|
||||
int32_t getRefCnt() const { return fRefCnt; }
|
||||
|
||||
/** May return true if the caller is the only owner.
|
||||
* Ensures that all previous owner's actions are complete.
|
||||
*/
|
||||
bool unique() const {
|
||||
// We believe we're reading fRefCnt in a safe way here, so we stifle the TSAN warning about
|
||||
// an unproctected read. Generally, don't read fRefCnt, and don't stifle this warning.
|
||||
bool const unique = (1 == SK_ANNOTATE_UNPROTECTED_READ(fRefCnt));
|
||||
if (unique) {
|
||||
// Acquire barrier (L/SL), if not provided by load of fRefCnt.
|
||||
// Prevents user's 'unique' code from happening before decrements.
|
||||
//TODO: issue the barrier.
|
||||
}
|
||||
return unique;
|
||||
}
|
||||
|
||||
/** Increment the reference count. Must be balanced by a call to unref().
|
||||
*/
|
||||
void ref() const {
|
||||
@ -75,18 +60,26 @@ public:
|
||||
SkASSERT(fRefCnt > 0);
|
||||
// Release barrier (SL/S), if not provided below.
|
||||
if (sk_atomic_dec(&fRefCnt) == 1) {
|
||||
// Acquire barrier (L/SL), if not provided above.
|
||||
// Aquire barrier (L/SL), if not provided above.
|
||||
// Prevents code in dispose from happening before the decrement.
|
||||
sk_membar_acquire__after_atomic_dec();
|
||||
sk_membar_aquire__after_atomic_dec();
|
||||
internal_dispose();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
void validate() const {
|
||||
SkASSERT(fRefCnt > 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Alias for ref(), for compatibility with scoped_refptr.
|
||||
*/
|
||||
void AddRef() { this->ref(); }
|
||||
|
||||
/**
|
||||
* Alias for unref(), for compatibility with scoped_refptr.
|
||||
*/
|
||||
void Release() { this->unref(); }
|
||||
|
||||
protected:
|
||||
/**
|
||||
@ -111,24 +104,15 @@ private:
|
||||
SkDELETE(this);
|
||||
}
|
||||
|
||||
// The following friends are those which override internal_dispose()
|
||||
// and conditionally call SkRefCnt::internal_dispose().
|
||||
friend class GrTexture;
|
||||
friend class SkWeakRefCnt;
|
||||
friend class GrTexture; // to allow GrTexture's internal_dispose to
|
||||
// call SkRefCnt's & directly set fRefCnt (to 1)
|
||||
|
||||
mutable int32_t fRefCnt;
|
||||
|
||||
typedef SkNoncopyable INHERITED;
|
||||
};
|
||||
|
||||
#ifdef SK_REF_CNT_MIXIN_INCLUDE
|
||||
// It is the responsibility of the following include to define the type SkRefCnt.
|
||||
// This SkRefCnt should normally derive from SkRefCntBase.
|
||||
#include SK_REF_CNT_MIXIN_INCLUDE
|
||||
#else
|
||||
class SK_API SkRefCnt : public SkRefCntBase { };
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Helper macro to safely assign one SkRefCnt[TS]* to another, checking for
|
||||
@ -168,13 +152,6 @@ template <typename T> static inline void SkSafeUnref(T* obj) {
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T> static inline void SkSafeSetNull(T*& obj) {
|
||||
if (NULL != obj) {
|
||||
obj->unref();
|
||||
obj = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
@ -212,13 +189,12 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* BlockRef<B> is a type which inherits from B, cannot be created,
|
||||
* cannot be deleted, and makes ref and unref private.
|
||||
* BlockRef<B> is a type which inherits from B, cannot be created,
|
||||
* and makes ref and unref private.
|
||||
*/
|
||||
template<typename B> class BlockRef : public B {
|
||||
private:
|
||||
BlockRef();
|
||||
~BlockRef();
|
||||
void ref() const;
|
||||
void unref() const;
|
||||
};
|
||||
@ -240,13 +216,11 @@ public:
|
||||
private:
|
||||
T* fObj;
|
||||
};
|
||||
// Can't use the #define trick below to guard a bare SkAutoTUnref(...) because it's templated. :(
|
||||
|
||||
class SkAutoUnref : public SkAutoTUnref<SkRefCnt> {
|
||||
public:
|
||||
SkAutoUnref(SkRefCnt* obj) : SkAutoTUnref<SkRefCnt>(obj) {}
|
||||
};
|
||||
#define SkAutoUnref(...) SK_REQUIRE_LOCAL_VAR(SkAutoUnref)
|
||||
|
||||
class SkAutoRef : SkNoncopyable {
|
||||
public:
|
||||
@ -255,7 +229,6 @@ public:
|
||||
private:
|
||||
SkRefCnt* fObj;
|
||||
};
|
||||
#define SkAutoRef(...) SK_REQUIRE_LOCAL_VAR(SkAutoRef)
|
||||
|
||||
/** Wrapper class for SkRefCnt pointers. This manages ref/unref of a pointer to
|
||||
a SkRefCnt (or subclass) object.
|
@ -85,16 +85,6 @@ public:
|
||||
*/
|
||||
const SkIRect& getBounds() const { return fBounds; }
|
||||
|
||||
/**
|
||||
* Returns a value that grows approximately linearly with the number of
|
||||
* intervals comprised in the region. Empty region will return 0, Rect
|
||||
* will return 1, Complex will return a value > 1.
|
||||
*
|
||||
* Use this to compare two regions, where the larger count likely
|
||||
* indicates a more complex region.
|
||||
*/
|
||||
int computeRegionComplexity() const;
|
||||
|
||||
/**
|
||||
* Returns true if the region is non-empty, and if so, appends the
|
||||
* boundary(s) of the region to the specified path.
|
||||
@ -361,16 +351,13 @@ public:
|
||||
* Write the region to the buffer, and return the number of bytes written.
|
||||
* If buffer is NULL, it still returns the number of bytes.
|
||||
*/
|
||||
size_t writeToMemory(void* buffer) const;
|
||||
uint32_t writeToMemory(void* buffer) const;
|
||||
|
||||
/**
|
||||
* Initializes the region from the buffer
|
||||
*
|
||||
* @param buffer Memory to read from
|
||||
* @param length Amount of memory available in the buffer
|
||||
* @return number of bytes read (must be a multiple of 4) or
|
||||
* 0 if there was not enough memory available
|
||||
* Initialized the region from the buffer, returning the number
|
||||
* of bytes actually read.
|
||||
*/
|
||||
size_t readFromMemory(const void* buffer, size_t length);
|
||||
uint32_t readFromMemory(const void* buffer);
|
||||
|
||||
/**
|
||||
* Returns a reference to a global empty region. Just a convenience for
|
379
gfx/skia/include/core/SkScalar.h
Normal file
379
gfx/skia/include/core/SkScalar.h
Normal file
@ -0,0 +1,379 @@
|
||||
|
||||
/*
|
||||
* 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 SkScalar_DEFINED
|
||||
#define SkScalar_DEFINED
|
||||
|
||||
#include "SkFixed.h"
|
||||
#include "SkFloatingPoint.h"
|
||||
|
||||
/** \file SkScalar.h
|
||||
|
||||
Types and macros for the data type SkScalar. This is the fractional numeric type
|
||||
that, depending on the compile-time flag SK_SCALAR_IS_FLOAT, may be implemented
|
||||
either as an IEEE float, or as a 16.16 SkFixed. The macros in this file are written
|
||||
to allow the calling code to manipulate SkScalar values without knowing which representation
|
||||
is in effect.
|
||||
*/
|
||||
|
||||
#ifdef SK_SCALAR_IS_FLOAT
|
||||
|
||||
/** SkScalar is our type for fractional values and coordinates. Depending on
|
||||
compile configurations, it is either represented as an IEEE float, or
|
||||
as a 16.16 fixed point integer.
|
||||
*/
|
||||
typedef float SkScalar;
|
||||
|
||||
/** SK_Scalar1 is defined to be 1.0 represented as an SkScalar
|
||||
*/
|
||||
#define SK_Scalar1 (1.0f)
|
||||
/** SK_Scalar1 is defined to be 1/2 represented as an SkScalar
|
||||
*/
|
||||
#define SK_ScalarHalf (0.5f)
|
||||
/** SK_ScalarInfinity is defined to be infinity as an SkScalar
|
||||
*/
|
||||
#define SK_ScalarInfinity SK_FloatInfinity
|
||||
/** SK_ScalarNegativeInfinity is defined to be negative infinity as an SkScalar
|
||||
*/
|
||||
#define SK_ScalarNegativeInfinity SK_FloatNegativeInfinity
|
||||
/** SK_ScalarMax is defined to be the largest value representable as an SkScalar
|
||||
*/
|
||||
#define SK_ScalarMax (3.402823466e+38f)
|
||||
/** SK_ScalarMin is defined to be the smallest value representable as an SkScalar
|
||||
*/
|
||||
#define SK_ScalarMin (-SK_ScalarMax)
|
||||
/** SK_ScalarNaN is defined to be 'Not a Number' as an SkScalar
|
||||
*/
|
||||
#define SK_ScalarNaN SK_FloatNaN
|
||||
/** SkScalarIsNaN(n) returns true if argument is not a number
|
||||
*/
|
||||
static inline bool SkScalarIsNaN(float x) { return x != x; }
|
||||
|
||||
/** Returns true if x is not NaN and not infinite */
|
||||
static inline bool SkScalarIsFinite(float x) {
|
||||
// We rely on the following behavior of infinities and nans
|
||||
// 0 * finite --> 0
|
||||
// 0 * infinity --> NaN
|
||||
// 0 * NaN --> NaN
|
||||
float prod = x * 0;
|
||||
// At this point, prod will either be NaN or 0
|
||||
// Therefore we can return (prod == prod) or (0 == prod).
|
||||
return prod == prod;
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
/** SkIntToScalar(n) returns its integer argument as an SkScalar
|
||||
*
|
||||
* If we're compiling in DEBUG mode, and can thus afford some extra runtime
|
||||
* cycles, check to make sure that the parameter passed in has not already
|
||||
* been converted to SkScalar. (A double conversion like this is harmless
|
||||
* for SK_SCALAR_IS_FLOAT, but for SK_SCALAR_IS_FIXED this causes trouble.)
|
||||
*
|
||||
* Note that we need all of these method signatures to properly handle the
|
||||
* various types that we pass into SkIntToScalar() to date:
|
||||
* int, size_t, U8CPU, etc., even though what we really mean is "anything
|
||||
* but a float".
|
||||
*/
|
||||
static inline float SkIntToScalar(signed int param) {
|
||||
return (float)param;
|
||||
}
|
||||
static inline float SkIntToScalar(unsigned int param) {
|
||||
return (float)param;
|
||||
}
|
||||
static inline float SkIntToScalar(signed long param) {
|
||||
return (float)param;
|
||||
}
|
||||
static inline float SkIntToScalar(unsigned long param) {
|
||||
return (float)param;
|
||||
}
|
||||
static inline float SkIntToScalar(float /* param */) {
|
||||
/* If the parameter passed into SkIntToScalar is a float,
|
||||
* one of two things has happened:
|
||||
* 1. the parameter was an SkScalar (which is typedef'd to float)
|
||||
* 2. the parameter was a float instead of an int
|
||||
*
|
||||
* Either way, it's not good.
|
||||
*/
|
||||
SkDEBUGFAIL("looks like you passed an SkScalar into SkIntToScalar");
|
||||
return (float)0;
|
||||
}
|
||||
#else // not SK_DEBUG
|
||||
/** SkIntToScalar(n) returns its integer argument as an SkScalar
|
||||
*/
|
||||
#define SkIntToScalar(n) ((float)(n))
|
||||
#endif // not SK_DEBUG
|
||||
/** SkFixedToScalar(n) returns its SkFixed argument as an SkScalar
|
||||
*/
|
||||
#define SkFixedToScalar(x) SkFixedToFloat(x)
|
||||
/** SkScalarToFixed(n) returns its SkScalar argument as an SkFixed
|
||||
*/
|
||||
#define SkScalarToFixed(x) SkFloatToFixed(x)
|
||||
|
||||
#define SkScalarToFloat(n) (n)
|
||||
#define SkFloatToScalar(n) (n)
|
||||
|
||||
#define SkScalarToDouble(n) (double)(n)
|
||||
#define SkDoubleToScalar(n) (float)(n)
|
||||
|
||||
/** SkScalarFraction(x) returns the signed fractional part of the argument
|
||||
*/
|
||||
#define SkScalarFraction(x) sk_float_mod(x, 1.0f)
|
||||
|
||||
#define SkScalarFloorToScalar(x) sk_float_floor(x)
|
||||
#define SkScalarCeilToScalar(x) sk_float_ceil(x)
|
||||
#define SkScalarRoundToScalar(x) sk_float_floor((x) + 0.5f)
|
||||
|
||||
#define SkScalarFloorToInt(x) sk_float_floor2int(x)
|
||||
#define SkScalarCeilToInt(x) sk_float_ceil2int(x)
|
||||
#define SkScalarRoundToInt(x) sk_float_round2int(x)
|
||||
#define SkScalarTruncToInt(x) static_cast<int>(x)
|
||||
|
||||
/** Returns the absolute value of the specified SkScalar
|
||||
*/
|
||||
#define SkScalarAbs(x) sk_float_abs(x)
|
||||
/** Return x with the sign of y
|
||||
*/
|
||||
#define SkScalarCopySign(x, y) sk_float_copysign(x, y)
|
||||
/** Returns the value pinned between 0 and max inclusive
|
||||
*/
|
||||
inline SkScalar SkScalarClampMax(SkScalar x, SkScalar max) {
|
||||
return x < 0 ? 0 : x > max ? max : x;
|
||||
}
|
||||
/** Returns the value pinned between min and max inclusive
|
||||
*/
|
||||
inline SkScalar SkScalarPin(SkScalar x, SkScalar min, SkScalar max) {
|
||||
return x < min ? min : x > max ? max : x;
|
||||
}
|
||||
/** Returns the specified SkScalar squared (x*x)
|
||||
*/
|
||||
inline SkScalar SkScalarSquare(SkScalar x) { return x * x; }
|
||||
/** Returns the product of two SkScalars
|
||||
*/
|
||||
#define SkScalarMul(a, b) ((float)(a) * (b))
|
||||
/** Returns the product of two SkScalars plus a third SkScalar
|
||||
*/
|
||||
#define SkScalarMulAdd(a, b, c) ((float)(a) * (b) + (c))
|
||||
/** Returns the product of a SkScalar and an int rounded to the nearest integer value
|
||||
*/
|
||||
#define SkScalarMulRound(a, b) SkScalarRound((float)(a) * (b))
|
||||
/** Returns the product of a SkScalar and an int promoted to the next larger int
|
||||
*/
|
||||
#define SkScalarMulCeil(a, b) SkScalarCeil((float)(a) * (b))
|
||||
/** Returns the product of a SkScalar and an int truncated to the next smaller int
|
||||
*/
|
||||
#define SkScalarMulFloor(a, b) SkScalarFloor((float)(a) * (b))
|
||||
/** Returns the quotient of two SkScalars (a/b)
|
||||
*/
|
||||
#define SkScalarDiv(a, b) ((float)(a) / (b))
|
||||
/** Returns the mod of two SkScalars (a mod b)
|
||||
*/
|
||||
#define SkScalarMod(x,y) sk_float_mod(x,y)
|
||||
/** Returns the product of the first two arguments, divided by the third argument
|
||||
*/
|
||||
#define SkScalarMulDiv(a, b, c) ((float)(a) * (b) / (c))
|
||||
/** Returns the multiplicative inverse of the SkScalar (1/x)
|
||||
*/
|
||||
#define SkScalarInvert(x) (SK_Scalar1 / (x))
|
||||
#define SkScalarFastInvert(x) (SK_Scalar1 / (x))
|
||||
/** Returns the square root of the SkScalar
|
||||
*/
|
||||
#define SkScalarSqrt(x) sk_float_sqrt(x)
|
||||
/** Returns b to the e
|
||||
*/
|
||||
#define SkScalarPow(b, e) sk_float_pow(b, e)
|
||||
/** Returns the average of two SkScalars (a+b)/2
|
||||
*/
|
||||
#define SkScalarAve(a, b) (((a) + (b)) * 0.5f)
|
||||
/** Returns the geometric mean of two SkScalars
|
||||
*/
|
||||
#define SkScalarMean(a, b) sk_float_sqrt((float)(a) * (b))
|
||||
/** Returns one half of the specified SkScalar
|
||||
*/
|
||||
#define SkScalarHalf(a) ((a) * 0.5f)
|
||||
|
||||
#define SK_ScalarSqrt2 1.41421356f
|
||||
#define SK_ScalarPI 3.14159265f
|
||||
#define SK_ScalarTanPIOver8 0.414213562f
|
||||
#define SK_ScalarRoot2Over2 0.707106781f
|
||||
|
||||
#define SkDegreesToRadians(degrees) ((degrees) * (SK_ScalarPI / 180))
|
||||
float SkScalarSinCos(SkScalar radians, SkScalar* cosValue);
|
||||
#define SkScalarSin(radians) (float)sk_float_sin(radians)
|
||||
#define SkScalarCos(radians) (float)sk_float_cos(radians)
|
||||
#define SkScalarTan(radians) (float)sk_float_tan(radians)
|
||||
#define SkScalarASin(val) (float)sk_float_asin(val)
|
||||
#define SkScalarACos(val) (float)sk_float_acos(val)
|
||||
#define SkScalarATan2(y, x) (float)sk_float_atan2(y,x)
|
||||
#define SkScalarExp(x) (float)sk_float_exp(x)
|
||||
#define SkScalarLog(x) (float)sk_float_log(x)
|
||||
|
||||
inline SkScalar SkMaxScalar(SkScalar a, SkScalar b) { return a > b ? a : b; }
|
||||
inline SkScalar SkMinScalar(SkScalar a, SkScalar b) { return a < b ? a : b; }
|
||||
|
||||
static inline bool SkScalarIsInt(SkScalar x) {
|
||||
return x == (float)(int)x;
|
||||
}
|
||||
#else
|
||||
typedef SkFixed SkScalar;
|
||||
|
||||
#define SK_Scalar1 SK_Fixed1
|
||||
#define SK_ScalarHalf SK_FixedHalf
|
||||
#define SK_ScalarInfinity SK_FixedMax
|
||||
#define SK_ScalarNegativeInfinity SK_FixedMin
|
||||
#define SK_ScalarMax SK_FixedMax
|
||||
#define SK_ScalarMin SK_FixedMin
|
||||
#define SK_ScalarNaN SK_FixedNaN
|
||||
#define SkScalarIsNaN(x) ((x) == SK_FixedNaN)
|
||||
#define SkScalarIsFinite(x) ((x) != SK_FixedNaN)
|
||||
|
||||
#define SkIntToScalar(n) SkIntToFixed(n)
|
||||
#define SkFixedToScalar(x) (x)
|
||||
#define SkScalarToFixed(x) (x)
|
||||
#define SkScalarToFloat(n) SkFixedToFloat(n)
|
||||
#define SkFloatToScalar(n) SkFloatToFixed(n)
|
||||
|
||||
#define SkScalarToDouble(n) SkFixedToDouble(n)
|
||||
#define SkDoubleToScalar(n) SkDoubleToFixed(n)
|
||||
#define SkScalarFraction(x) SkFixedFraction(x)
|
||||
|
||||
#define SkScalarFloorToScalar(x) SkFixedFloorToFixed(x)
|
||||
#define SkScalarCeilToScalar(x) SkFixedCeilToFixed(x)
|
||||
#define SkScalarRoundToScalar(x) SkFixedRoundToFixed(x)
|
||||
|
||||
#define SkScalarFloorToInt(x) SkFixedFloorToInt(x)
|
||||
#define SkScalarCeilToInt(x) SkFixedCeilToInt(x)
|
||||
#define SkScalarRoundToInt(x) SkFixedRoundToInt(x)
|
||||
#define SkScalarTruncToInt(x) (((x) < 0) ? SkScalarCeilToInt(x) : SkScalarFloorToInt(x))
|
||||
|
||||
#define SkScalarAbs(x) SkFixedAbs(x)
|
||||
#define SkScalarCopySign(x, y) SkCopySign32(x, y)
|
||||
#define SkScalarClampMax(x, max) SkClampMax(x, max)
|
||||
#define SkScalarPin(x, min, max) SkPin32(x, min, max)
|
||||
#define SkScalarSquare(x) SkFixedSquare(x)
|
||||
#define SkScalarMul(a, b) SkFixedMul(a, b)
|
||||
#define SkScalarMulAdd(a, b, c) SkFixedMulAdd(a, b, c)
|
||||
#define SkScalarMulRound(a, b) SkFixedMulCommon(a, b, SK_FixedHalf)
|
||||
#define SkScalarMulCeil(a, b) SkFixedMulCommon(a, b, SK_Fixed1 - 1)
|
||||
#define SkScalarMulFloor(a, b) SkFixedMulCommon(a, b, 0)
|
||||
#define SkScalarDiv(a, b) SkFixedDiv(a, b)
|
||||
#define SkScalarMod(a, b) SkFixedMod(a, b)
|
||||
#define SkScalarMulDiv(a, b, c) SkMulDiv(a, b, c)
|
||||
#define SkScalarInvert(x) SkFixedInvert(x)
|
||||
#define SkScalarFastInvert(x) SkFixedFastInvert(x)
|
||||
#define SkScalarSqrt(x) SkFixedSqrt(x)
|
||||
#define SkScalarAve(a, b) SkFixedAve(a, b)
|
||||
#define SkScalarMean(a, b) SkFixedMean(a, b)
|
||||
#define SkScalarHalf(a) ((a) >> 1)
|
||||
|
||||
#define SK_ScalarSqrt2 SK_FixedSqrt2
|
||||
#define SK_ScalarPI SK_FixedPI
|
||||
#define SK_ScalarTanPIOver8 SK_FixedTanPIOver8
|
||||
#define SK_ScalarRoot2Over2 SK_FixedRoot2Over2
|
||||
|
||||
#define SkDegreesToRadians(degrees) SkFractMul(degrees, SK_FractPIOver180)
|
||||
#define SkScalarSinCos(radians, cosPtr) SkFixedSinCos(radians, cosPtr)
|
||||
#define SkScalarSin(radians) SkFixedSin(radians)
|
||||
#define SkScalarCos(radians) SkFixedCos(radians)
|
||||
#define SkScalarTan(val) SkFixedTan(val)
|
||||
#define SkScalarASin(val) SkFixedASin(val)
|
||||
#define SkScalarACos(val) SkFixedACos(val)
|
||||
#define SkScalarATan2(y, x) SkFixedATan2(y,x)
|
||||
#define SkScalarExp(x) SkFixedExp(x)
|
||||
#define SkScalarLog(x) SkFixedLog(x)
|
||||
|
||||
#define SkMaxScalar(a, b) SkMax32(a, b)
|
||||
#define SkMinScalar(a, b) SkMin32(a, b)
|
||||
|
||||
static inline bool SkScalarIsInt(SkFixed x) {
|
||||
return 0 == (x & 0xffff);
|
||||
}
|
||||
#endif
|
||||
|
||||
// DEPRECATED : use ToInt or ToScalar variant
|
||||
#define SkScalarFloor(x) SkScalarFloorToInt(x)
|
||||
#define SkScalarCeil(x) SkScalarCeilToInt(x)
|
||||
#define SkScalarRound(x) SkScalarRoundToInt(x)
|
||||
|
||||
/**
|
||||
* Returns -1 || 0 || 1 depending on the sign of value:
|
||||
* -1 if x < 0
|
||||
* 0 if x == 0
|
||||
* 1 if x > 0
|
||||
*/
|
||||
static inline int SkScalarSignAsInt(SkScalar x) {
|
||||
return x < 0 ? -1 : (x > 0);
|
||||
}
|
||||
|
||||
// Scalar result version of above
|
||||
static inline SkScalar SkScalarSignAsScalar(SkScalar x) {
|
||||
return x < 0 ? -SK_Scalar1 : ((x > 0) ? SK_Scalar1 : 0);
|
||||
}
|
||||
|
||||
#define SK_ScalarNearlyZero (SK_Scalar1 / (1 << 12))
|
||||
|
||||
static inline bool SkScalarNearlyZero(SkScalar x,
|
||||
SkScalar tolerance = SK_ScalarNearlyZero) {
|
||||
SkASSERT(tolerance >= 0);
|
||||
return SkScalarAbs(x) <= tolerance;
|
||||
}
|
||||
|
||||
static inline bool SkScalarNearlyEqual(SkScalar x, SkScalar y,
|
||||
SkScalar tolerance = SK_ScalarNearlyZero) {
|
||||
SkASSERT(tolerance >= 0);
|
||||
return SkScalarAbs(x-y) <= tolerance;
|
||||
}
|
||||
|
||||
/** Linearly interpolate between A and B, based on t.
|
||||
If t is 0, return A
|
||||
If t is 1, return B
|
||||
else interpolate.
|
||||
t must be [0..SK_Scalar1]
|
||||
*/
|
||||
static inline SkScalar SkScalarInterp(SkScalar A, SkScalar B, SkScalar t) {
|
||||
SkASSERT(t >= 0 && t <= SK_Scalar1);
|
||||
return A + SkScalarMul(B - A, t);
|
||||
}
|
||||
|
||||
static inline SkScalar SkScalarLog2(SkScalar x) {
|
||||
static const SkScalar log2_conversion_factor = SkScalarDiv(1, SkScalarLog(2));
|
||||
|
||||
return SkScalarMul(SkScalarLog(x), log2_conversion_factor);
|
||||
}
|
||||
|
||||
/** Interpolate along the function described by (keys[length], values[length])
|
||||
for the passed searchKey. SearchKeys outside the range keys[0]-keys[Length]
|
||||
clamp to the min or max value. This function was inspired by a desire
|
||||
to change the multiplier for thickness in fakeBold; therefore it assumes
|
||||
the number of pairs (length) will be small, and a linear search is used.
|
||||
Repeated keys are allowed for discontinuous functions (so long as keys is
|
||||
monotonically increasing), and if key is the value of a repeated scalar in
|
||||
keys, the first one will be used. However, that may change if a binary
|
||||
search is used.
|
||||
*/
|
||||
SkScalar SkScalarInterpFunc(SkScalar searchKey, const SkScalar keys[],
|
||||
const SkScalar values[], int length);
|
||||
|
||||
/*
|
||||
* Helper to compare an array of scalars.
|
||||
*/
|
||||
static inline bool SkScalarsEqual(const SkScalar a[], const SkScalar b[], int n) {
|
||||
#ifdef SK_SCALAR_IS_FLOAT
|
||||
SkASSERT(n >= 0);
|
||||
for (int i = 0; i < n; ++i) {
|
||||
if (a[i] != b[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
return 0 == memcmp(a, b, n * sizeof(SkScalar));
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
@ -1,3 +1,4 @@
|
||||
|
||||
/*
|
||||
* Copyright 2006 The Android Open Source Project
|
||||
*
|
||||
@ -311,17 +312,14 @@ public:
|
||||
SkPoint fPoint[2]; //!< Type specific, see above.
|
||||
SkScalar fRadius[2]; //!< Type specific, see above.
|
||||
TileMode fTileMode; //!< The tile mode used.
|
||||
uint32_t fGradientFlags; //!< see SkGradientShader::Flags
|
||||
};
|
||||
|
||||
virtual GradientType asAGradient(GradientInfo* info) const;
|
||||
|
||||
/**
|
||||
* If the shader subclass has a GrEffect implementation, this resturns the effect to install.
|
||||
* The incoming color to the effect has r=g=b=a all extracted from the SkPaint's alpha.
|
||||
* The output color should be the computed SkShader premul color modulated by the incoming
|
||||
* color. The GrContext may be used by the effect to create textures. The GPU device does not
|
||||
* call setContext. Instead we pass the SkPaint here in case the shader needs paint info.
|
||||
* If the shader subclass has a GrEffect implementation, this installs an effect on the stage.
|
||||
* The GrContext may be used by the effect to create textures. The GPU device does not call
|
||||
* setContext. Instead we pass the paint here in case the shader needs paint info.
|
||||
*/
|
||||
virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint& paint) const;
|
||||
|
||||
@ -334,9 +332,6 @@ public:
|
||||
* exceed implementation limits (currently at 64K - 1)) then SkEmptyShader
|
||||
* may be returned.
|
||||
*
|
||||
* If the src is kA8_Config then that mask will be colorized using the color on
|
||||
* the paint.
|
||||
*
|
||||
* @param src The bitmap to use inside the shader
|
||||
* @param tmx The tiling mode to use when sampling the bitmap in the x-direction.
|
||||
* @param tmy The tiling mode to use when sampling the bitmap in the y-direction.
|
||||
@ -347,8 +342,6 @@ public:
|
||||
|
||||
SkDEVCODE(virtual void toString(SkString* str) const;)
|
||||
|
||||
SK_DEFINE_FLATTENABLE_TYPE(SkShader)
|
||||
|
||||
protected:
|
||||
enum MatrixClass {
|
||||
kLinear_MatrixClass, // no perspective
|
||||
@ -359,15 +352,17 @@ protected:
|
||||
|
||||
// These can be called by your subclass after setContext() has been called
|
||||
uint8_t getPaintAlpha() const { return fPaintAlpha; }
|
||||
SkBitmap::Config getDeviceConfig() const { return (SkBitmap::Config)fDeviceConfig; }
|
||||
const SkMatrix& getTotalInverse() const { return fTotalInverse; }
|
||||
MatrixClass getInverseClass() const { return (MatrixClass)fTotalInverseClass; }
|
||||
|
||||
SkShader(SkReadBuffer& );
|
||||
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
|
||||
SkShader(SkFlattenableReadBuffer& );
|
||||
virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
|
||||
private:
|
||||
SkMatrix fLocalMatrix;
|
||||
SkMatrix fTotalInverse;
|
||||
uint8_t fPaintAlpha;
|
||||
uint8_t fDeviceConfig;
|
||||
uint8_t fTotalInverseClass;
|
||||
SkDEBUGCODE(SkBool8 fInSetContext;)
|
||||
|
@ -90,19 +90,19 @@ struct SkSize : public SkTSize<SkScalar> {
|
||||
|
||||
SkISize toRound() const {
|
||||
SkISize s;
|
||||
s.set(SkScalarRoundToInt(fWidth), SkScalarRoundToInt(fHeight));
|
||||
s.set(SkScalarRound(fWidth), SkScalarRound(fHeight));
|
||||
return s;
|
||||
}
|
||||
|
||||
SkISize toCeil() const {
|
||||
SkISize s;
|
||||
s.set(SkScalarCeilToInt(fWidth), SkScalarCeilToInt(fHeight));
|
||||
s.set(SkScalarCeil(fWidth), SkScalarCeil(fHeight));
|
||||
return s;
|
||||
}
|
||||
|
||||
SkISize toFloor() const {
|
||||
SkISize s;
|
||||
s.set(SkScalarFloorToInt(fWidth), SkScalarFloorToInt(fHeight));
|
||||
s.set(SkScalarFloor(fWidth), SkScalarFloor(fHeight));
|
||||
return s;
|
||||
}
|
||||
};
|
397
gfx/skia/include/core/SkStream.h
Normal file
397
gfx/skia/include/core/SkStream.h
Normal file
@ -0,0 +1,397 @@
|
||||
|
||||
/*
|
||||
* 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 SkStream_DEFINED
|
||||
#define SkStream_DEFINED
|
||||
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkScalar.h"
|
||||
|
||||
class SkData;
|
||||
|
||||
class SK_API SkStream : public SkRefCnt {
|
||||
public:
|
||||
/**
|
||||
* Attempts to open the specified file, and return a stream to it (using
|
||||
* mmap if available). On success, the caller must call unref() on the
|
||||
* returned object. On failure, returns NULL.
|
||||
*/
|
||||
static SkStream* NewFromFile(const char path[]);
|
||||
|
||||
SK_DECLARE_INST_COUNT(SkStream)
|
||||
|
||||
/** Called to rewind to the beginning of the stream. If this cannot be
|
||||
done, return false.
|
||||
*/
|
||||
virtual bool rewind() = 0;
|
||||
/** If this stream represents a file, this method returns the file's name.
|
||||
If it does not, it returns NULL (the default behavior).
|
||||
*/
|
||||
virtual const char* getFileName();
|
||||
/** Called to read or skip size number of bytes.
|
||||
If buffer is NULL and size > 0, skip that many bytes, returning how many were skipped.
|
||||
If buffer is NULL and size == 0, return the total length of the stream.
|
||||
If buffer != NULL, copy the requested number of bytes into buffer, returning how many were copied.
|
||||
@param buffer If buffer is NULL, ignore and just skip size bytes, otherwise copy size bytes into buffer
|
||||
@param size The number of bytes to skip or copy
|
||||
@return bytes read on success
|
||||
*/
|
||||
virtual size_t read(void* buffer, size_t size) = 0;
|
||||
|
||||
/** Return the total length of the stream.
|
||||
*/
|
||||
size_t getLength() { return this->read(NULL, 0); }
|
||||
|
||||
/** Skip the specified number of bytes, returning the actual number
|
||||
of bytes that could be skipped.
|
||||
*/
|
||||
size_t skip(size_t bytes);
|
||||
|
||||
/** If the stream is backed by RAM, this method returns the starting
|
||||
address for the data. If not (i.e. it is backed by a file or other
|
||||
structure), this method returns NULL.
|
||||
The default implementation returns NULL.
|
||||
*/
|
||||
virtual const void* getMemoryBase();
|
||||
|
||||
int8_t readS8();
|
||||
int16_t readS16();
|
||||
int32_t readS32();
|
||||
|
||||
uint8_t readU8() { return (uint8_t)this->readS8(); }
|
||||
uint16_t readU16() { return (uint16_t)this->readS16(); }
|
||||
uint32_t readU32() { return (uint32_t)this->readS32(); }
|
||||
|
||||
bool readBool() { return this->readU8() != 0; }
|
||||
SkScalar readScalar();
|
||||
size_t readPackedUInt();
|
||||
|
||||
/**
|
||||
* Reconstitute an SkData object that was written to the stream
|
||||
* using SkWStream::writeData().
|
||||
*/
|
||||
SkData* readData();
|
||||
|
||||
private:
|
||||
typedef SkRefCnt INHERITED;
|
||||
};
|
||||
|
||||
class SK_API SkWStream : SkNoncopyable {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT_ROOT(SkWStream)
|
||||
|
||||
virtual ~SkWStream();
|
||||
|
||||
/** Called to write bytes to a SkWStream. Returns true on success
|
||||
@param buffer the address of at least size bytes to be written to the stream
|
||||
@param size The number of bytes in buffer to write to the stream
|
||||
@return true on success
|
||||
*/
|
||||
virtual bool write(const void* buffer, size_t size) = 0;
|
||||
virtual void newline();
|
||||
virtual void flush();
|
||||
|
||||
// helpers
|
||||
|
||||
bool write8(U8CPU);
|
||||
bool write16(U16CPU);
|
||||
bool write32(uint32_t);
|
||||
|
||||
bool writeText(const char text[]);
|
||||
bool writeDecAsText(int32_t);
|
||||
bool writeBigDecAsText(int64_t, int minDigits = 0);
|
||||
bool writeHexAsText(uint32_t, int minDigits = 0);
|
||||
bool writeScalarAsText(SkScalar);
|
||||
|
||||
bool writeBool(bool v) { return this->write8(v); }
|
||||
bool writeScalar(SkScalar);
|
||||
bool writePackedUInt(size_t);
|
||||
|
||||
bool writeStream(SkStream* input, size_t length);
|
||||
|
||||
/**
|
||||
* Append an SkData object to the stream, such that it can be read
|
||||
* out of the stream using SkStream::readData().
|
||||
*
|
||||
* Note that the encoding method used to write the SkData object
|
||||
* to the stream may change over time. This method DOES NOT
|
||||
* just write the raw content of the SkData object to the stream.
|
||||
*/
|
||||
bool writeData(const SkData*);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "SkString.h"
|
||||
|
||||
struct SkFILE;
|
||||
|
||||
/** A stream that reads from a FILE*, which is opened in the constructor and
|
||||
closed in the destructor
|
||||
*/
|
||||
class SK_API SkFILEStream : public SkStream {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkFILEStream)
|
||||
|
||||
/** Initialize the stream by calling fopen on the specified path. Will be
|
||||
closed in the destructor.
|
||||
*/
|
||||
explicit SkFILEStream(const char path[] = NULL);
|
||||
virtual ~SkFILEStream();
|
||||
|
||||
/** Returns true if the current path could be opened.
|
||||
*/
|
||||
bool isValid() const { return fFILE != NULL; }
|
||||
/** Close the current file, and open a new file with the specified
|
||||
path. If path is NULL, just close the current file.
|
||||
*/
|
||||
void setPath(const char path[]);
|
||||
|
||||
virtual bool rewind() SK_OVERRIDE;
|
||||
virtual size_t read(void* buffer, size_t size) SK_OVERRIDE;
|
||||
virtual const char* getFileName() SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
SkFILE* fFILE;
|
||||
SkString fName;
|
||||
|
||||
typedef SkStream INHERITED;
|
||||
};
|
||||
|
||||
/** A stream that reads from a file descriptor
|
||||
*/
|
||||
class SK_API SkFDStream : public SkStream {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkFDStream)
|
||||
|
||||
/** Initialize the stream with a dup() of the specified file descriptor.
|
||||
If closeWhenDone is true, then the descriptor will be closed in the
|
||||
destructor.
|
||||
*/
|
||||
SkFDStream(int fileDesc, bool closeWhenDone);
|
||||
virtual ~SkFDStream();
|
||||
|
||||
/** Returns true if the current path could be opened.
|
||||
*/
|
||||
bool isValid() const { return fFD >= 0; }
|
||||
|
||||
virtual bool rewind() SK_OVERRIDE;
|
||||
virtual size_t read(void* buffer, size_t size) SK_OVERRIDE;
|
||||
virtual const char* getFileName() SK_OVERRIDE { return NULL; }
|
||||
|
||||
private:
|
||||
int fFD;
|
||||
bool fCloseWhenDone;
|
||||
|
||||
typedef SkStream INHERITED;
|
||||
};
|
||||
|
||||
class SK_API SkMemoryStream : public SkStream {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkMemoryStream)
|
||||
|
||||
SkMemoryStream();
|
||||
/** We allocate (and free) the memory. Write to it via getMemoryBase()
|
||||
*/
|
||||
SkMemoryStream(size_t length);
|
||||
/** if copyData is true, the stream makes a private copy of the data
|
||||
*/
|
||||
SkMemoryStream(const void* data, size_t length, bool copyData = false);
|
||||
|
||||
/**
|
||||
* Use the specified data as the memory for this stream. The stream will
|
||||
* call ref() on the data (assuming it is not null).
|
||||
*/
|
||||
SkMemoryStream(SkData*);
|
||||
|
||||
virtual ~SkMemoryStream();
|
||||
|
||||
/** Resets the stream to the specified data and length,
|
||||
just like the constructor.
|
||||
if copyData is true, the stream makes a private copy of the data
|
||||
*/
|
||||
virtual void setMemory(const void* data, size_t length,
|
||||
bool copyData = false);
|
||||
/** Replace any memory buffer with the specified buffer. The caller
|
||||
must have allocated data with sk_malloc or sk_realloc, since it
|
||||
will be freed with sk_free.
|
||||
*/
|
||||
void setMemoryOwned(const void* data, size_t length);
|
||||
|
||||
/**
|
||||
* Return the stream's data in a SkData. The caller must call unref() when
|
||||
* it is finished using the data.
|
||||
*/
|
||||
SkData* copyToData() const;
|
||||
|
||||
/**
|
||||
* Use the specified data as the memory for this stream. The stream will
|
||||
* call ref() on the data (assuming it is not null). The function returns
|
||||
* the data parameter as a convenience.
|
||||
*/
|
||||
SkData* setData(SkData*);
|
||||
|
||||
void skipToAlign4();
|
||||
virtual bool rewind() SK_OVERRIDE;
|
||||
virtual size_t read(void* buffer, size_t size) SK_OVERRIDE;
|
||||
virtual const void* getMemoryBase() SK_OVERRIDE;
|
||||
const void* getAtPos();
|
||||
size_t seek(size_t offset);
|
||||
size_t peek() const { return fOffset; }
|
||||
|
||||
private:
|
||||
SkData* fData;
|
||||
size_t fOffset;
|
||||
|
||||
typedef SkStream INHERITED;
|
||||
};
|
||||
|
||||
/** \class SkBufferStream
|
||||
This is a wrapper class that adds buffering to another stream.
|
||||
The caller can provide the buffer, or ask SkBufferStream to allocated/free
|
||||
it automatically.
|
||||
*/
|
||||
class SK_API SkBufferStream : public SkStream {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkBufferStream)
|
||||
|
||||
/** Provide the stream to be buffered (proxy), and the size of the buffer that
|
||||
should be used. This will be allocated and freed automatically. If bufferSize is 0,
|
||||
a default buffer size will be used.
|
||||
The proxy stream is referenced, and will be unreferenced in when the
|
||||
bufferstream is destroyed.
|
||||
*/
|
||||
SkBufferStream(SkStream* proxy, size_t bufferSize = 0);
|
||||
/** Provide the stream to be buffered (proxy), and a buffer and size to be used.
|
||||
This buffer is owned by the caller, and must be at least bufferSize bytes big.
|
||||
Passing NULL for buffer will cause the buffer to be allocated/freed automatically.
|
||||
If buffer is not NULL, it is an error for bufferSize to be 0.
|
||||
The proxy stream is referenced, and will be unreferenced in when the
|
||||
bufferstream is destroyed.
|
||||
*/
|
||||
SkBufferStream(SkStream* proxy, void* buffer, size_t bufferSize);
|
||||
virtual ~SkBufferStream();
|
||||
|
||||
virtual bool rewind() SK_OVERRIDE;
|
||||
virtual const char* getFileName() SK_OVERRIDE;
|
||||
virtual size_t read(void* buffer, size_t size) SK_OVERRIDE;
|
||||
virtual const void* getMemoryBase() SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
enum {
|
||||
kDefaultBufferSize = 128
|
||||
};
|
||||
// illegal
|
||||
SkBufferStream(const SkBufferStream&);
|
||||
SkBufferStream& operator=(const SkBufferStream&);
|
||||
|
||||
SkStream* fProxy;
|
||||
char* fBuffer;
|
||||
size_t fOrigBufferSize, fBufferSize, fBufferOffset;
|
||||
bool fWeOwnTheBuffer;
|
||||
|
||||
void init(void*, size_t);
|
||||
|
||||
typedef SkStream INHERITED;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class SK_API SkFILEWStream : public SkWStream {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkFILEWStream)
|
||||
|
||||
SkFILEWStream(const char path[]);
|
||||
virtual ~SkFILEWStream();
|
||||
|
||||
/** Returns true if the current path could be opened.
|
||||
*/
|
||||
bool isValid() const { return fFILE != NULL; }
|
||||
|
||||
virtual bool write(const void* buffer, size_t size) SK_OVERRIDE;
|
||||
virtual void flush() SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
SkFILE* fFILE;
|
||||
|
||||
typedef SkWStream INHERITED;
|
||||
};
|
||||
|
||||
class SkMemoryWStream : public SkWStream {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkMemoryWStream)
|
||||
|
||||
SkMemoryWStream(void* buffer, size_t size);
|
||||
virtual bool write(const void* buffer, size_t size) SK_OVERRIDE;
|
||||
size_t bytesWritten() const { return fBytesWritten; }
|
||||
|
||||
private:
|
||||
char* fBuffer;
|
||||
size_t fMaxLength;
|
||||
size_t fBytesWritten;
|
||||
|
||||
typedef SkWStream INHERITED;
|
||||
};
|
||||
|
||||
class SK_API SkDynamicMemoryWStream : public SkWStream {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkDynamicMemoryWStream)
|
||||
|
||||
SkDynamicMemoryWStream();
|
||||
virtual ~SkDynamicMemoryWStream();
|
||||
|
||||
virtual bool write(const void* buffer, size_t size) SK_OVERRIDE;
|
||||
// random access write
|
||||
// modifies stream and returns true if offset + size is less than or equal to getOffset()
|
||||
bool write(const void* buffer, size_t offset, size_t size);
|
||||
bool read(void* buffer, size_t offset, size_t size);
|
||||
size_t getOffset() const { return fBytesWritten; }
|
||||
size_t bytesWritten() const { return fBytesWritten; }
|
||||
|
||||
// copy what has been written to the stream into dst
|
||||
void copyTo(void* dst) const;
|
||||
|
||||
/**
|
||||
* Return a copy of the data written so far. This call is responsible for
|
||||
* calling unref() when they are finished with the data.
|
||||
*/
|
||||
SkData* copyToData() const;
|
||||
|
||||
// reset the stream to its original state
|
||||
void reset();
|
||||
void padToAlign4();
|
||||
private:
|
||||
struct Block;
|
||||
Block* fHead;
|
||||
Block* fTail;
|
||||
size_t fBytesWritten;
|
||||
mutable SkData* fCopy; // is invalidated if we write after it is created
|
||||
|
||||
void invalidateCopy();
|
||||
|
||||
typedef SkWStream INHERITED;
|
||||
};
|
||||
|
||||
|
||||
class SK_API SkDebugWStream : public SkWStream {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkDebugWStream)
|
||||
|
||||
// overrides
|
||||
virtual bool write(const void* buffer, size_t size) SK_OVERRIDE;
|
||||
virtual void newline() SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
typedef SkWStream INHERITED;
|
||||
};
|
||||
|
||||
// for now
|
||||
typedef SkFILEStream SkURLStream;
|
||||
|
||||
#endif
|
@ -11,7 +11,6 @@
|
||||
#define SkString_DEFINED
|
||||
|
||||
#include "SkScalar.h"
|
||||
#include "SkTArray.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
@ -60,14 +59,9 @@ static inline char *SkStrDup(const char string[]) {
|
||||
|
||||
|
||||
|
||||
#define SkStrAppendU32_MaxSize 10
|
||||
char* SkStrAppendU32(char buffer[], uint32_t);
|
||||
#define SkStrAppendU64_MaxSize 20
|
||||
char* SkStrAppendU64(char buffer[], uint64_t, int minDigits);
|
||||
|
||||
#define SkStrAppendS32_MaxSize (SkStrAppendU32_MaxSize + 1)
|
||||
#define SkStrAppendS32_MaxSize 11
|
||||
char* SkStrAppendS32(char buffer[], int32_t);
|
||||
#define SkStrAppendS64_MaxSize (SkStrAppendU64_MaxSize + 1)
|
||||
#define SkStrAppendS64_MaxSize 20
|
||||
char* SkStrAppendS64(char buffer[], int64_t, int minDigits);
|
||||
|
||||
/**
|
||||
@ -86,7 +80,11 @@ char* SkStrAppendS64(char buffer[], int64_t, int minDigits);
|
||||
* Thus if the caller wants to add a 0 at the end, buffer must be at least
|
||||
* SkStrAppendScalar_MaxSize + 1 bytes large.
|
||||
*/
|
||||
#define SkStrAppendScalar SkStrAppendFloat
|
||||
#ifdef SK_SCALAR_IS_FLOAT
|
||||
#define SkStrAppendScalar SkStrAppendFloat
|
||||
#else
|
||||
#define SkStrAppendScalar SkStrAppendFixed
|
||||
#endif
|
||||
|
||||
char* SkStrAppendFloat(char buffer[], float);
|
||||
char* SkStrAppendFixed(char buffer[], SkFixed);
|
||||
@ -166,8 +164,6 @@ public:
|
||||
void insertUnichar(size_t offset, SkUnichar);
|
||||
void insertS32(size_t offset, int32_t value);
|
||||
void insertS64(size_t offset, int64_t value, int minDigits = 0);
|
||||
void insertU32(size_t offset, uint32_t value);
|
||||
void insertU64(size_t offset, uint64_t value, int minDigits = 0);
|
||||
void insertHex(size_t offset, uint32_t value, int minDigits = 0);
|
||||
void insertScalar(size_t offset, SkScalar);
|
||||
|
||||
@ -177,8 +173,6 @@ public:
|
||||
void appendUnichar(SkUnichar uni) { this->insertUnichar((size_t)-1, uni); }
|
||||
void appendS32(int32_t value) { this->insertS32((size_t)-1, value); }
|
||||
void appendS64(int64_t value, int minDigits = 0) { this->insertS64((size_t)-1, value, minDigits); }
|
||||
void appendU32(uint32_t value) { this->insertU32((size_t)-1, value); }
|
||||
void appendU64(uint64_t value, int minDigits = 0) { this->insertU64((size_t)-1, value, minDigits); }
|
||||
void appendHex(uint32_t value, int minDigits = 0) { this->insertHex((size_t)-1, value, minDigits); }
|
||||
void appendScalar(SkScalar value) { this->insertScalar((size_t)-1, value); }
|
||||
|
||||
@ -193,7 +187,7 @@ public:
|
||||
|
||||
void printf(const char format[], ...) SK_PRINTF_LIKE(2, 3);
|
||||
void appendf(const char format[], ...) SK_PRINTF_LIKE(2, 3);
|
||||
void appendVAList(const char format[], va_list);
|
||||
void appendf(const char format[], va_list);
|
||||
void prependf(const char format[], ...) SK_PRINTF_LIKE(2, 3);
|
||||
|
||||
void remove(size_t offset, size_t length);
|
||||
@ -211,7 +205,7 @@ public:
|
||||
private:
|
||||
struct Rec {
|
||||
public:
|
||||
uint32_t fLength; // logically size_t, but we want it to stay 32bits
|
||||
size_t fLength;
|
||||
int32_t fRefCnt;
|
||||
char fBeginningOfData;
|
||||
|
||||
@ -232,6 +226,24 @@ private:
|
||||
static Rec* RefRec(Rec*);
|
||||
};
|
||||
|
||||
class SkAutoUCS2 {
|
||||
public:
|
||||
SkAutoUCS2(const char utf8[]);
|
||||
~SkAutoUCS2();
|
||||
|
||||
/** This returns the number of ucs2 characters
|
||||
*/
|
||||
int count() const { return fCount; }
|
||||
|
||||
/** This returns a null terminated ucs2 string
|
||||
*/
|
||||
const uint16_t* getUCS2() const { return fUCS2; }
|
||||
|
||||
private:
|
||||
int fCount;
|
||||
uint16_t* fUCS2;
|
||||
};
|
||||
|
||||
/// Creates a new string and writes into it using a printf()-style format.
|
||||
SkString SkStringPrintf(const char* format, ...);
|
||||
|
||||
@ -241,7 +253,4 @@ template <> inline void SkTSwap(SkString& a, SkString& b) {
|
||||
a.swap(b);
|
||||
}
|
||||
|
||||
// Split str on any characters in delimiters into out. (Think, strtok with a sane API.)
|
||||
void SkStrSplit(const char* str, const char* delimiters, SkTArray<SkString>* out);
|
||||
|
||||
#endif
|
@ -81,14 +81,6 @@ public:
|
||||
*/
|
||||
bool applyToPath(SkPath* dst, const SkPath& src) const;
|
||||
|
||||
bool operator==(const SkStrokeRec& other) const {
|
||||
return fWidth == other.fWidth &&
|
||||
fMiterLimit == other.fMiterLimit &&
|
||||
fCap == other.fCap &&
|
||||
fJoin == other.fJoin &&
|
||||
fStrokeAndFill == other.fStrokeAndFill;
|
||||
}
|
||||
|
||||
private:
|
||||
SkScalar fWidth;
|
||||
SkScalar fMiterLimit;
|
@ -24,7 +24,7 @@ class GrRenderTarget;
|
||||
* To draw into a canvas, first create the appropriate type of Surface, and
|
||||
* then request the canvas from the surface.
|
||||
*/
|
||||
class SK_API SkSurface : public SkRefCnt {
|
||||
class SkSurface : public SkRefCnt {
|
||||
public:
|
||||
SK_DECLARE_INST_COUNT(SkSurface)
|
||||
|
||||
@ -35,7 +35,7 @@ public:
|
||||
* If the requested surface cannot be created, or the request is not a
|
||||
* supported configuration, NULL will be returned.
|
||||
*/
|
||||
static SkSurface* NewRasterDirect(const SkImageInfo&, void* pixels, size_t rowBytes);
|
||||
static SkSurface* NewRasterDirect(const SkImage::Info&, void* pixels, size_t rowBytes);
|
||||
|
||||
/**
|
||||
* Return a new surface, with the memory for the pixels automatically
|
||||
@ -44,19 +44,7 @@ public:
|
||||
* If the requested surface cannot be created, or the request is not a
|
||||
* supported configuration, NULL will be returned.
|
||||
*/
|
||||
static SkSurface* NewRaster(const SkImageInfo&);
|
||||
|
||||
/**
|
||||
* Helper version of NewRaster. It creates a SkImageInfo with the
|
||||
* specified width and height, and populates the rest of info to match
|
||||
* pixels in SkPMColor format.
|
||||
*/
|
||||
static SkSurface* NewRasterPMColor(int width, int height) {
|
||||
SkImageInfo info = {
|
||||
width, height, kPMColor_SkColorType, kPremul_SkAlphaType
|
||||
};
|
||||
return NewRaster(info);
|
||||
}
|
||||
static SkSurface* NewRaster(const SkImage::Info&);
|
||||
|
||||
/**
|
||||
* Return a new surface whose contents will be recorded into a picture.
|
||||
@ -68,13 +56,13 @@ public:
|
||||
/**
|
||||
* Return a new surface using the specified render target.
|
||||
*/
|
||||
static SkSurface* NewRenderTargetDirect(GrRenderTarget*);
|
||||
static SkSurface* NewRenderTargetDirect(GrContext*, GrRenderTarget*);
|
||||
|
||||
/**
|
||||
* Return a new surface whose contents will be drawn to an offscreen
|
||||
* render target, allocated by the surface.
|
||||
*/
|
||||
static SkSurface* NewRenderTarget(GrContext*, const SkImageInfo&, int sampleCount = 0);
|
||||
static SkSurface* NewRenderTarget(GrContext*, const SkImage::Info&, int sampleCount = 0);
|
||||
|
||||
int width() const { return fWidth; }
|
||||
int height() const { return fHeight; }
|
||||
@ -91,26 +79,10 @@ public:
|
||||
uint32_t generationID();
|
||||
|
||||
/**
|
||||
* Modes that can be passed to notifyContentWillChange
|
||||
*/
|
||||
enum ContentChangeMode {
|
||||
/**
|
||||
* Use this mode if it is known that the upcoming content changes will
|
||||
* clear or overwrite prior contents, thus making them discardable.
|
||||
*/
|
||||
kDiscard_ContentChangeMode,
|
||||
/**
|
||||
* Use this mode if prior surface contents need to be preserved or
|
||||
* if in doubt.
|
||||
*/
|
||||
kRetain_ContentChangeMode,
|
||||
};
|
||||
|
||||
/**
|
||||
* Call this if the contents are about to change. This will (lazily) force a new
|
||||
* Call this if the contents have changed. This will (lazily) force a new
|
||||
* value to be returned from generationID() when it is called next.
|
||||
*/
|
||||
void notifyContentWillChange(ContentChangeMode mode);
|
||||
void notifyContentChanged();
|
||||
|
||||
/**
|
||||
* Return a canvas that will draw into this surface. This will always
|
||||
@ -133,14 +105,14 @@ public:
|
||||
* ... // draw using canvasB
|
||||
* canvasA->drawSurface(surfaceB); // <--- this will always be optimal!
|
||||
*/
|
||||
SkSurface* newSurface(const SkImageInfo&);
|
||||
SkSurface* newSurface(const SkImage::Info&);
|
||||
|
||||
/**
|
||||
* Returns an image of the current state of the surface pixels up to this
|
||||
* point. Subsequent changes to the surface (by drawing into its canvas)
|
||||
* will not be reflected in this image.
|
||||
*/
|
||||
SkImage* newImageSnapshot();
|
||||
SkImage* newImageShapshot();
|
||||
|
||||
/**
|
||||
* Thought the caller could get a snapshot image explicitly, and draw that,
|
||||
@ -153,7 +125,6 @@ public:
|
||||
|
||||
protected:
|
||||
SkSurface(int width, int height);
|
||||
SkSurface(const SkImageInfo&);
|
||||
|
||||
// called by subclass if their contents have changed
|
||||
void dirtyGenerationID() {
|
@ -28,21 +28,19 @@ inline void copyAndDelete(SkTArray<T, true>* self, char* newMemArray) {
|
||||
template<typename T>
|
||||
inline void copy(SkTArray<T, false>* self, const T* array) {
|
||||
for (int i = 0; i < self->fCount; ++i) {
|
||||
SkNEW_PLACEMENT_ARGS(self->fItemArray + i, T, (array[i]));
|
||||
new (self->fItemArray + i) T(array[i]);
|
||||
}
|
||||
}
|
||||
template<typename T>
|
||||
inline void copyAndDelete(SkTArray<T, false>* self, char* newMemArray) {
|
||||
for (int i = 0; i < self->fCount; ++i) {
|
||||
SkNEW_PLACEMENT_ARGS(newMemArray + sizeof(T) * i, T, (self->fItemArray[i]));
|
||||
new (newMemArray + sizeof(T) * i) T(self->fItemArray[i]);
|
||||
self->fItemArray[i].~T();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template <typename T, bool MEM_COPY> void* operator new(size_t, SkTArray<T, MEM_COPY>*, int);
|
||||
|
||||
/** When MEM_COPY is true T will be bit copied when moved.
|
||||
When MEM_COPY is false, T will be copy constructed / destructed.
|
||||
In all cases T's constructor will be called on allocation,
|
||||
@ -93,7 +91,7 @@ public:
|
||||
fItemArray[i].~T();
|
||||
}
|
||||
fCount = 0;
|
||||
this->checkRealloc((int)array.count());
|
||||
checkRealloc((int)array.count());
|
||||
fCount = array.count();
|
||||
SkTArrayExt::copy(this, static_cast<const T*>(array.fMemArray));
|
||||
return *this;
|
||||
@ -113,23 +111,6 @@ public:
|
||||
*/
|
||||
void reset() { this->pop_back_n(fCount); }
|
||||
|
||||
/**
|
||||
* Resets to count() = n newly constructed T objects.
|
||||
*/
|
||||
void reset(int n) {
|
||||
SkASSERT(n >= 0);
|
||||
for (int i = 0; i < fCount; ++i) {
|
||||
fItemArray[i].~T();
|
||||
}
|
||||
// set fCount to 0 before calling checkRealloc so that no copy cons. are called.
|
||||
fCount = 0;
|
||||
this->checkRealloc(n);
|
||||
fCount = n;
|
||||
for (int i = 0; i < fCount; ++i) {
|
||||
SkNEW_PLACEMENT(fItemArray + i, T);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets to a copy of a C array.
|
||||
*/
|
||||
@ -161,18 +142,20 @@ public:
|
||||
* elements.
|
||||
*/
|
||||
T& push_back() {
|
||||
T* newT = reinterpret_cast<T*>(this->push_back_raw(1));
|
||||
SkNEW_PLACEMENT(newT, T);
|
||||
return *newT;
|
||||
checkRealloc(1);
|
||||
new ((char*)fMemArray+sizeof(T)*fCount) T;
|
||||
++fCount;
|
||||
return fItemArray[fCount-1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Version of above that uses a copy constructor to initialize the new item
|
||||
*/
|
||||
T& push_back(const T& t) {
|
||||
T* newT = reinterpret_cast<T*>(this->push_back_raw(1));
|
||||
SkNEW_PLACEMENT_ARGS(newT, T, (t));
|
||||
return *newT;
|
||||
checkRealloc(1);
|
||||
new ((char*)fMemArray+sizeof(T)*fCount) T(t);
|
||||
++fCount;
|
||||
return fItemArray[fCount-1];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -182,11 +165,12 @@ public:
|
||||
*/
|
||||
T* push_back_n(int n) {
|
||||
SkASSERT(n >= 0);
|
||||
T* newTs = reinterpret_cast<T*>(this->push_back_raw(n));
|
||||
checkRealloc(n);
|
||||
for (int i = 0; i < n; ++i) {
|
||||
SkNEW_PLACEMENT(newTs + i, T);
|
||||
new (fItemArray + fCount + i) T;
|
||||
}
|
||||
return newTs;
|
||||
fCount += n;
|
||||
return fItemArray + fCount - n;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -195,11 +179,12 @@ public:
|
||||
*/
|
||||
T* push_back_n(int n, const T& t) {
|
||||
SkASSERT(n >= 0);
|
||||
T* newTs = reinterpret_cast<T*>(this->push_back_raw(n));
|
||||
checkRealloc(n);
|
||||
for (int i = 0; i < n; ++i) {
|
||||
SkNEW_PLACEMENT_ARGS(newTs[i], T, (t));
|
||||
new (fItemArray + fCount + i) T(t);
|
||||
}
|
||||
return newTs;
|
||||
fCount += n;
|
||||
return fItemArray + fCount - n;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -208,9 +193,9 @@ public:
|
||||
*/
|
||||
T* push_back_n(int n, const T t[]) {
|
||||
SkASSERT(n >= 0);
|
||||
this->checkRealloc(n);
|
||||
checkRealloc(n);
|
||||
for (int i = 0; i < n; ++i) {
|
||||
SkNEW_PLACEMENT_ARGS(fItemArray + fCount + i, T, (t[i]));
|
||||
new (fItemArray + fCount + i) T(t[i]);
|
||||
}
|
||||
fCount += n;
|
||||
return fItemArray + fCount - n;
|
||||
@ -223,7 +208,7 @@ public:
|
||||
SkASSERT(fCount > 0);
|
||||
--fCount;
|
||||
fItemArray[fCount].~T();
|
||||
this->checkRealloc(0);
|
||||
checkRealloc(0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -234,9 +219,9 @@ public:
|
||||
SkASSERT(fCount >= n);
|
||||
fCount -= n;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
fItemArray[fCount + i].~T();
|
||||
fItemArray[i].~T();
|
||||
}
|
||||
this->checkRealloc(0);
|
||||
checkRealloc(0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -247,9 +232,9 @@ public:
|
||||
SkASSERT(newCount >= 0);
|
||||
|
||||
if (newCount > fCount) {
|
||||
this->push_back_n(newCount - fCount);
|
||||
push_back_n(newCount - fCount);
|
||||
} else if (newCount < fCount) {
|
||||
this->pop_back_n(fCount - newCount);
|
||||
pop_back_n(fCount - newCount);
|
||||
}
|
||||
}
|
||||
|
||||
@ -382,15 +367,6 @@ private:
|
||||
|
||||
static const int gMIN_ALLOC_COUNT = 8;
|
||||
|
||||
// Helper function that makes space for n objects, adjusts the count, but does not initialize
|
||||
// the new objects.
|
||||
void* push_back_raw(int n) {
|
||||
this->checkRealloc(n);
|
||||
void* ptr = fItemArray + fCount;
|
||||
fCount += n;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
inline void checkRealloc(int delta) {
|
||||
SkASSERT(fCount >= 0);
|
||||
SkASSERT(fAllocCount >= 0);
|
||||
@ -425,8 +401,6 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
friend void* operator new<T>(size_t, SkTArray*, int);
|
||||
|
||||
template<typename X> friend void SkTArrayExt::copy(SkTArray<X, true>* that, const X*);
|
||||
template<typename X> friend void SkTArrayExt::copyAndDelete(SkTArray<X, true>* that, char*);
|
||||
|
||||
@ -443,29 +417,6 @@ private:
|
||||
};
|
||||
};
|
||||
|
||||
// Use the below macro (SkNEW_APPEND_TO_TARRAY) rather than calling this directly
|
||||
template <typename T, bool MEM_COPY>
|
||||
void* operator new(size_t, SkTArray<T, MEM_COPY>* array, int atIndex) {
|
||||
// Currently, we only support adding to the end of the array. When the array class itself
|
||||
// supports random insertion then this should be updated.
|
||||
// SkASSERT(atIndex >= 0 && atIndex <= array->count());
|
||||
SkASSERT(atIndex == array->count());
|
||||
return array->push_back_raw(1);
|
||||
}
|
||||
|
||||
// Skia doesn't use C++ exceptions but it may be compiled with them enabled. Having an op delete
|
||||
// to match the op new silences warnings about missing op delete when a constructor throws an
|
||||
// exception.
|
||||
template <typename T, bool MEM_COPY>
|
||||
void operator delete(void*, SkTArray<T, MEM_COPY>* array, int atIndex) {
|
||||
SK_CRASH();
|
||||
}
|
||||
|
||||
// Constructs a new object as the last element of an SkTArray.
|
||||
#define SkNEW_APPEND_TO_TARRAY(array_ptr, type_name, args) \
|
||||
(new ((array_ptr), (array_ptr)->count()) type_name args)
|
||||
|
||||
|
||||
/**
|
||||
* Subclass of SkTArray that contains a preallocated memory block for the array.
|
||||
*/
|
||||
@ -486,10 +437,6 @@ public:
|
||||
: INHERITED(array, &fStorage) {
|
||||
}
|
||||
|
||||
explicit SkSTArray(int reserveCount)
|
||||
: INHERITED(reserveCount) {
|
||||
}
|
||||
|
||||
SkSTArray(const T* array, int count)
|
||||
: INHERITED(array, count, &fStorage) {
|
||||
}
|
@ -21,7 +21,7 @@ public:
|
||||
fData = NULL;
|
||||
#endif
|
||||
}
|
||||
SkTDArray(const T src[], int count) {
|
||||
SkTDArray(const T src[], size_t count) {
|
||||
SkASSERT(src || count == 0);
|
||||
|
||||
fReserve = fCount = 0;
|
||||
@ -69,9 +69,6 @@ public:
|
||||
(a.fCount == 0 ||
|
||||
!memcmp(a.fArray, b.fArray, a.fCount * sizeof(T)));
|
||||
}
|
||||
friend bool operator!=(const SkTDArray<T>& a, const SkTDArray<T>& b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
void swap(SkTDArray<T>& other) {
|
||||
SkTSwap(fArray, other.fArray);
|
||||
@ -98,14 +95,7 @@ public:
|
||||
/**
|
||||
* Return the number of elements in the array
|
||||
*/
|
||||
int count() const { return fCount; }
|
||||
|
||||
/**
|
||||
* Return the total number of elements allocated.
|
||||
* reserved() - count() gives you the number of elements you can add
|
||||
* without causing an allocation.
|
||||
*/
|
||||
int reserved() const { return fReserve; }
|
||||
int count() const { return (int)fCount; }
|
||||
|
||||
/**
|
||||
* return the number of bytes in the array: count * sizeof(T)
|
||||
@ -118,11 +108,11 @@ public:
|
||||
const T* end() const { return fArray ? fArray + fCount : NULL; }
|
||||
|
||||
T& operator[](int index) {
|
||||
SkASSERT(index < fCount);
|
||||
SkASSERT((unsigned)index < fCount);
|
||||
return fArray[index];
|
||||
}
|
||||
const T& operator[](int index) const {
|
||||
SkASSERT(index < fCount);
|
||||
SkASSERT((unsigned)index < fCount);
|
||||
return fArray[index];
|
||||
}
|
||||
|
||||
@ -151,43 +141,25 @@ public:
|
||||
fCount = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the number of elements in the array.
|
||||
* If the array does not have space for count elements, it will increase
|
||||
* the storage allocated to some amount greater than that required.
|
||||
* It will never shrink the shrink the storage.
|
||||
*/
|
||||
void setCount(int count) {
|
||||
// TODO(mtklein): eliminate this method, setCountExact -> setCount
|
||||
SkASSERT(count >= 0);
|
||||
void setCount(size_t count) {
|
||||
if (count > fReserve) {
|
||||
this->resizeStorageToAtLeast(count);
|
||||
this->growBy(count - fCount);
|
||||
} else {
|
||||
fCount = count;
|
||||
}
|
||||
fCount = count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the number of elements in the array.
|
||||
* If the array does not have space for count elements, it will increase
|
||||
* the storage allocated to exactly the amount required, with no remaining
|
||||
* reserved space.
|
||||
* It will never shrink the shrink the storage.
|
||||
*/
|
||||
void setCountExact(int count) {
|
||||
if (count > fReserve) {
|
||||
this->resizeStorageToExact(count);
|
||||
}
|
||||
fCount = count;
|
||||
}
|
||||
|
||||
void setReserve(int reserve) {
|
||||
void setReserve(size_t reserve) {
|
||||
if (reserve > fReserve) {
|
||||
this->resizeStorageToAtLeast(reserve);
|
||||
SkASSERT(reserve > fCount);
|
||||
size_t count = fCount;
|
||||
this->growBy(reserve - fCount);
|
||||
fCount = count;
|
||||
}
|
||||
}
|
||||
|
||||
T* prepend() {
|
||||
this->adjustCount(1);
|
||||
this->growBy(1);
|
||||
memmove(fArray + 1, fArray, (fCount - 1) * sizeof(T));
|
||||
return fArray;
|
||||
}
|
||||
@ -195,13 +167,13 @@ public:
|
||||
T* append() {
|
||||
return this->append(1, NULL);
|
||||
}
|
||||
T* append(int count, const T* src = NULL) {
|
||||
int oldCount = fCount;
|
||||
T* append(size_t count, const T* src = NULL) {
|
||||
size_t oldCount = fCount;
|
||||
if (count) {
|
||||
SkASSERT(src == NULL || fArray == NULL ||
|
||||
src + count <= fArray || fArray + oldCount <= src);
|
||||
|
||||
this->adjustCount(count);
|
||||
this->growBy(count);
|
||||
if (src) {
|
||||
memcpy(fArray + oldCount, src, sizeof(T) * count);
|
||||
}
|
||||
@ -215,14 +187,14 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
T* insert(int index) {
|
||||
T* insert(size_t index) {
|
||||
return this->insert(index, 1, NULL);
|
||||
}
|
||||
T* insert(int index, int count, const T* src = NULL) {
|
||||
T* insert(size_t index, size_t count, const T* src = NULL) {
|
||||
SkASSERT(count);
|
||||
SkASSERT(index <= fCount);
|
||||
size_t oldCount = fCount;
|
||||
this->adjustCount(count);
|
||||
this->growBy(count);
|
||||
T* dst = fArray + index;
|
||||
memmove(dst + count, dst, sizeof(T) * (oldCount - index));
|
||||
if (src) {
|
||||
@ -231,15 +203,15 @@ public:
|
||||
return dst;
|
||||
}
|
||||
|
||||
void remove(int index, int count = 1) {
|
||||
void remove(size_t index, size_t count = 1) {
|
||||
SkASSERT(index + count <= fCount);
|
||||
fCount = fCount - count;
|
||||
memmove(fArray + index, fArray + index + count, sizeof(T) * (fCount - index));
|
||||
}
|
||||
|
||||
void removeShuffle(int index) {
|
||||
void removeShuffle(size_t index) {
|
||||
SkASSERT(index < fCount);
|
||||
int newCount = fCount - 1;
|
||||
size_t newCount = fCount - 1;
|
||||
fCount = newCount;
|
||||
if (index != newCount) {
|
||||
memcpy(fArray + index, fArray + newCount, sizeof(T));
|
||||
@ -264,7 +236,7 @@ public:
|
||||
|
||||
while (iter > stop) {
|
||||
if (*--iter == elem) {
|
||||
return SkToInt(iter - stop);
|
||||
return iter - stop;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
@ -281,7 +253,7 @@ public:
|
||||
* Copies up to max elements into dst. The number of items copied is
|
||||
* capped by count - index. The actual number copied is returned.
|
||||
*/
|
||||
int copyRange(T* dst, int index, int max) const {
|
||||
int copyRange(T* dst, size_t index, int max) const {
|
||||
SkASSERT(max >= 0);
|
||||
SkASSERT(!max || dst);
|
||||
if (index >= fCount) {
|
||||
@ -293,7 +265,7 @@ public:
|
||||
}
|
||||
|
||||
void copy(T* dst) const {
|
||||
this->copyRange(dst, 0, fCount);
|
||||
this->copyRange(0, fCount, dst);
|
||||
}
|
||||
|
||||
// routines to treat the array like a stack
|
||||
@ -371,46 +343,22 @@ private:
|
||||
ArrayT* fData;
|
||||
#endif
|
||||
T* fArray;
|
||||
int fReserve;
|
||||
int fCount;
|
||||
size_t fReserve, fCount;
|
||||
|
||||
/**
|
||||
* Adjusts the number of elements in the array.
|
||||
* This is the same as calling setCount(count() + delta).
|
||||
*/
|
||||
void adjustCount(int delta) {
|
||||
this->setCount(fCount + delta);
|
||||
}
|
||||
void growBy(size_t extra) {
|
||||
SkASSERT(extra);
|
||||
|
||||
/**
|
||||
* This resizes the storage to *exactly* count elements, growing or
|
||||
* shrinking the allocation as needed. It does not ASSERT anything about
|
||||
* the previous allocation size, or about fCount.
|
||||
*
|
||||
* note: does NOT modify fCount
|
||||
*/
|
||||
void resizeStorageToExact(int count) {
|
||||
SkASSERT(count >= 0);
|
||||
fArray = (T*)sk_realloc_throw(fArray, count * sizeof(T));
|
||||
if (fCount + extra > fReserve) {
|
||||
size_t size = fCount + extra + 4;
|
||||
size += size >> 2;
|
||||
|
||||
fArray = (T*)sk_realloc_throw(fArray, size * sizeof(T));
|
||||
#ifdef SK_DEBUG
|
||||
fData = (ArrayT*)fArray;
|
||||
fData = (ArrayT*)fArray;
|
||||
#endif
|
||||
fReserve = count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increase the storage allocation such that it can hold (fCount + extra)
|
||||
* elements.
|
||||
* It never shrinks the allocation, and it may increase the allocation by
|
||||
* more than is strictly required, based on a private growth heuristic.
|
||||
*
|
||||
* note: does NOT modify fCount
|
||||
*/
|
||||
void resizeStorageToAtLeast(int count) {
|
||||
SkASSERT(count > fReserve);
|
||||
int space = count + 4;
|
||||
space += space>>2;
|
||||
this->resizeStorageToExact(space);
|
||||
fReserve = size;
|
||||
}
|
||||
fCount += extra;
|
||||
}
|
||||
};
|
||||
|
@ -227,7 +227,7 @@ public:
|
||||
void validate() const {
|
||||
SkASSERT(!fHead == !fTail);
|
||||
Iter iter;
|
||||
for (T* item = iter.init(*this, Iter::kHead_IterStart); NULL != item; item = iter.next()) {
|
||||
for (T* item = iter.init(*this, Iter::kHead_IterStart); NULL != (item = iter.next()); ) {
|
||||
SkASSERT(this->isInList(item));
|
||||
if (NULL == item->fPrev) {
|
||||
SkASSERT(fHead == item);
|
@ -16,11 +16,11 @@
|
||||
and provides a function-pointer. This can be used to auto-register a set of
|
||||
services, e.g. a set of image codecs.
|
||||
*/
|
||||
template <typename T> class SkTRegistry : SkNoncopyable {
|
||||
template <typename T, typename P> class SkTRegistry : SkNoncopyable {
|
||||
public:
|
||||
typedef T Factory;
|
||||
typedef T (*Factory)(P);
|
||||
|
||||
explicit SkTRegistry(T fact) : fFact(fact) {
|
||||
SkTRegistry(Factory fact) {
|
||||
#ifdef SK_BUILD_FOR_ANDROID
|
||||
// work-around for double-initialization bug
|
||||
{
|
||||
@ -33,14 +33,15 @@ public:
|
||||
}
|
||||
}
|
||||
#endif
|
||||
fFact = fact;
|
||||
fChain = gHead;
|
||||
gHead = this;
|
||||
gHead = this;
|
||||
}
|
||||
|
||||
static const SkTRegistry* Head() { return gHead; }
|
||||
|
||||
const SkTRegistry* next() const { return fChain; }
|
||||
const Factory& factory() const { return fFact; }
|
||||
Factory factory() const { return fFact; }
|
||||
|
||||
private:
|
||||
Factory fFact;
|
||||
@ -50,6 +51,6 @@ private:
|
||||
};
|
||||
|
||||
// The caller still needs to declare an instance of this somewhere
|
||||
template <typename T> SkTRegistry<T>* SkTRegistry<T>::gHead;
|
||||
template <typename T, typename P> SkTRegistry<T, P>* SkTRegistry<T, P>::gHead;
|
||||
|
||||
#endif
|
76
gfx/skia/include/core/SkTScopedPtr.h
Normal file
76
gfx/skia/include/core/SkTScopedPtr.h
Normal file
@ -0,0 +1,76 @@
|
||||
|
||||
/*
|
||||
* 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 SkTScopedPtr_DEFINED
|
||||
#define SkTScopedPtr_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
/** \class SkTScopedPtr
|
||||
A SkTScopedPtr<T> is like a T*, except that the destructor of SkTScopedPtr<T>
|
||||
automatically deletes the pointer it holds (if any). That is, SkTScopedPtr<T>
|
||||
owns the T object that it points to. Like a T*, a SkTScopedPtr<T> may hold
|
||||
either NULL or a pointer to a T object. Also like T*, SkTScopedPtr<T> is
|
||||
thread-compatible, and once you dereference it, you get the threadsafety
|
||||
guarantees of T.
|
||||
|
||||
The size of a SkTScopedPtr is small: sizeof(SkTScopedPtr<T>) == sizeof(T*)
|
||||
*/
|
||||
template <typename T> class SkTScopedPtr : SkNoncopyable {
|
||||
public:
|
||||
explicit SkTScopedPtr(T* o = NULL) : fObj(o) {}
|
||||
~SkTScopedPtr() {
|
||||
enum { kTypeMustBeComplete = sizeof(T) };
|
||||
delete fObj;
|
||||
}
|
||||
|
||||
/** Delete the current object, if any. Then take ownership of the
|
||||
passed object.
|
||||
*/
|
||||
void reset(T* o = NULL) {
|
||||
if (o != fObj) {
|
||||
enum { kTypeMustBeComplete = sizeof(T) };
|
||||
delete fObj;
|
||||
fObj = o;
|
||||
}
|
||||
}
|
||||
|
||||
/** Without deleting the current object, return it and forget about it.
|
||||
Similar to calling get() and reset(), but the object is not deleted.
|
||||
*/
|
||||
T* release() {
|
||||
T* retVal = fObj;
|
||||
fObj = NULL;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
T& operator*() const {
|
||||
SkASSERT(fObj != NULL);
|
||||
return *fObj;
|
||||
}
|
||||
T* operator->() const {
|
||||
SkASSERT(fObj != NULL);
|
||||
return fObj;
|
||||
}
|
||||
T* get() const { return fObj; }
|
||||
|
||||
bool operator==(T* o) const { return fObj == o; }
|
||||
bool operator!=(T* o) const { return fObj != o; }
|
||||
|
||||
private:
|
||||
T* fObj;
|
||||
|
||||
// Forbid comparison of SkTScopedPtr types. If T2 != T, it doesn't make
|
||||
// sense, and if T2 == T, it still doesn't make sense because the same
|
||||
// object can't be owned by two different scoped_ptrs.
|
||||
template <class T2> bool operator==(SkTScopedPtr<T2> const& o2) const;
|
||||
template <class T2> bool operator!=(SkTScopedPtr<T2> const& o2) const;
|
||||
};
|
||||
|
||||
#endif
|
239
gfx/skia/include/core/SkTSearch.h
Normal file
239
gfx/skia/include/core/SkTSearch.h
Normal file
@ -0,0 +1,239 @@
|
||||
|
||||
/*
|
||||
* 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 SkTSearch_DEFINED
|
||||
#define SkTSearch_DEFINED
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
/**
|
||||
* All of the SkTSearch variants want to return the index (0...N-1) of the
|
||||
* found element, or the bit-not of where to insert the element.
|
||||
*
|
||||
* At a simple level, if the return value is negative, it was not found.
|
||||
*
|
||||
* For clients that want to insert the new element if it was not found, use
|
||||
* the following logic:
|
||||
*
|
||||
* int index = SkTSearch(...);
|
||||
* if (index >= 0) {
|
||||
* // found at index
|
||||
* } else {
|
||||
* index = ~index; // now we are positive
|
||||
* // insert at index
|
||||
* }
|
||||
*/
|
||||
|
||||
template <typename T>
|
||||
int SkTSearch(const T* base, int count, const T& target, size_t elemSize)
|
||||
{
|
||||
SkASSERT(count >= 0);
|
||||
if (count <= 0)
|
||||
return ~0;
|
||||
|
||||
SkASSERT(base != NULL); // base may be NULL if count is zero
|
||||
|
||||
int lo = 0;
|
||||
int hi = count - 1;
|
||||
|
||||
while (lo < hi)
|
||||
{
|
||||
int mid = (hi + lo) >> 1;
|
||||
const T* elem = (const T*)((const char*)base + mid * elemSize);
|
||||
|
||||
if (*elem < target)
|
||||
lo = mid + 1;
|
||||
else
|
||||
hi = mid;
|
||||
}
|
||||
|
||||
const T* elem = (const T*)((const char*)base + hi * elemSize);
|
||||
if (*elem != target)
|
||||
{
|
||||
if (*elem < target)
|
||||
hi += 1;
|
||||
hi = ~hi;
|
||||
}
|
||||
return hi;
|
||||
}
|
||||
|
||||
template <typename T, int (COMPARE)(const T*, const T*)>
|
||||
int SkTSearch(const T* base, int count, const T& target, size_t elemSize)
|
||||
{
|
||||
SkASSERT(count >= 0);
|
||||
if (count <= 0) {
|
||||
return ~0;
|
||||
}
|
||||
|
||||
SkASSERT(base != NULL); // base may be NULL if count is zero
|
||||
|
||||
int lo = 0;
|
||||
int hi = count - 1;
|
||||
|
||||
while (lo < hi) {
|
||||
int mid = (hi + lo) >> 1;
|
||||
const T* elem = (const T*)((const char*)base + mid * elemSize);
|
||||
|
||||
if (COMPARE(elem, &target) < 0)
|
||||
lo = mid + 1;
|
||||
else
|
||||
hi = mid;
|
||||
}
|
||||
|
||||
const T* elem = (const T*)((const char*)base + hi * elemSize);
|
||||
int pred = COMPARE(elem, &target);
|
||||
if (pred != 0) {
|
||||
if (pred < 0)
|
||||
hi += 1;
|
||||
hi = ~hi;
|
||||
}
|
||||
return hi;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int SkTSearch(const T* base, int count, const T& target, size_t elemSize,
|
||||
int (*compare)(const T*, const T*))
|
||||
{
|
||||
SkASSERT(count >= 0);
|
||||
if (count <= 0) {
|
||||
return ~0;
|
||||
}
|
||||
|
||||
SkASSERT(base != NULL); // base may be NULL if count is zero
|
||||
|
||||
int lo = 0;
|
||||
int hi = count - 1;
|
||||
|
||||
while (lo < hi) {
|
||||
int mid = (hi + lo) >> 1;
|
||||
const T* elem = (const T*)((const char*)base + mid * elemSize);
|
||||
|
||||
if ((*compare)(elem, &target) < 0)
|
||||
lo = mid + 1;
|
||||
else
|
||||
hi = mid;
|
||||
}
|
||||
|
||||
const T* elem = (const T*)((const char*)base + hi * elemSize);
|
||||
int pred = (*compare)(elem, &target);
|
||||
if (pred != 0) {
|
||||
if (pred < 0)
|
||||
hi += 1;
|
||||
hi = ~hi;
|
||||
}
|
||||
return hi;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int SkTSearch(const T** base, int count, const T* target, size_t elemSize,
|
||||
int (*compare)(const T*, const T*))
|
||||
{
|
||||
SkASSERT(count >= 0);
|
||||
if (count <= 0)
|
||||
return ~0;
|
||||
|
||||
SkASSERT(base != NULL); // base may be NULL if count is zero
|
||||
|
||||
int lo = 0;
|
||||
int hi = count - 1;
|
||||
|
||||
while (lo < hi)
|
||||
{
|
||||
int mid = (hi + lo) >> 1;
|
||||
const T* elem = *(const T**)((const char*)base + mid * elemSize);
|
||||
|
||||
if ((*compare)(elem, target) < 0)
|
||||
lo = mid + 1;
|
||||
else
|
||||
hi = mid;
|
||||
}
|
||||
|
||||
const T* elem = *(const T**)((const char*)base + hi * elemSize);
|
||||
int pred = (*compare)(elem, target);
|
||||
if (pred != 0)
|
||||
{
|
||||
if (pred < 0)
|
||||
hi += 1;
|
||||
hi = ~hi;
|
||||
}
|
||||
return hi;
|
||||
}
|
||||
|
||||
template <typename T, int (COMPARE)(const T*, const T*)>
|
||||
int SkTSearch(const T** base, int count, const T* target, size_t elemSize)
|
||||
{
|
||||
SkASSERT(count >= 0);
|
||||
if (count <= 0)
|
||||
return ~0;
|
||||
|
||||
SkASSERT(base != NULL); // base may be NULL if count is zero
|
||||
|
||||
int lo = 0;
|
||||
int hi = count - 1;
|
||||
|
||||
while (lo < hi)
|
||||
{
|
||||
int mid = (hi + lo) >> 1;
|
||||
const T* elem = *(const T**)((const char*)base + mid * elemSize);
|
||||
|
||||
if (COMPARE(elem, target) < 0)
|
||||
lo = mid + 1;
|
||||
else
|
||||
hi = mid;
|
||||
}
|
||||
|
||||
const T* elem = *(const T**)((const char*)base + hi * elemSize);
|
||||
int pred = COMPARE(elem, target);
|
||||
if (pred != 0)
|
||||
{
|
||||
if (pred < 0)
|
||||
hi += 1;
|
||||
hi = ~hi;
|
||||
}
|
||||
return hi;
|
||||
}
|
||||
int SkStrSearch(const char*const* base, int count, const char target[],
|
||||
size_t target_len, size_t elemSize);
|
||||
int SkStrSearch(const char*const* base, int count, const char target[],
|
||||
size_t elemSize);
|
||||
|
||||
/** Like SkStrSearch, but treats target as if it were all lower-case. Assumes that
|
||||
base points to a table of lower-case strings.
|
||||
*/
|
||||
int SkStrLCSearch(const char*const* base, int count, const char target[],
|
||||
size_t target_len, size_t elemSize);
|
||||
int SkStrLCSearch(const char*const* base, int count, const char target[],
|
||||
size_t elemSize);
|
||||
|
||||
/** Helper class to convert a string to lower-case, but only modifying the ascii
|
||||
characters. This makes the routine very fast and never changes the string
|
||||
length, but it is not suitable for linguistic purposes. Normally this is
|
||||
used for buiding and searching string tables.
|
||||
*/
|
||||
class SkAutoAsciiToLC {
|
||||
public:
|
||||
SkAutoAsciiToLC(const char str[], size_t len = (size_t)-1);
|
||||
~SkAutoAsciiToLC();
|
||||
|
||||
const char* lc() const { return fLC; }
|
||||
size_t length() const { return fLength; }
|
||||
|
||||
private:
|
||||
char* fLC; // points to either the heap or fStorage
|
||||
size_t fLength;
|
||||
enum {
|
||||
STORAGE = 64
|
||||
};
|
||||
char fStorage[STORAGE+1];
|
||||
};
|
||||
|
||||
// Helper when calling qsort with a compare proc that has typed its arguments
|
||||
#define SkCastForQSort(compare) reinterpret_cast<int (*)(const void*, const void*)>(compare)
|
||||
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user