Commit 191e99fb authored by Ivan.Shulga's avatar Ivan.Shulga Committed by Alexander Trofimov

added skia for gtk+ clipboard support

git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@56461 954022d7-b5bf-4e40-9824-e11837661b57
parent 996a3df9
junov@chromium.org
bsalomon@google.com
robertphillips@google.com
epoger@google.com
tomhudson@google.com
alokp@chromium.org
reed@google.com
vandebo@chromium.org
senorblanco@chromium.org
thakis@chromium.org
twiz@chromium.org
This is a copy of the Skia source tree. In the original repository, the include
directories and the "corecg" directories are separated out. On top of
libs/graphics -> skia
we have the following mappings from source repository to our tree:
include/corecg -> skia/include/corecg
include/graphics -> skia/include
libs/corecg -> skia/corecg
platform/* are our own files that provide extra functionality we need our
Skia to implement.
DO NOT CHANGE THE SKIA FILES IN OUR TREE. These will be overwritten when we
sync to newer versions of Skia. The exception is platform/
THE EXCEPTION IS include/corecg/SkUserConfig.h which are the application's
definition of its options and environment. This file must be manually merged
with any changes in the Skia tree so that our options are preserved and we
also pick up any important changes they make.
-- brettw@google.com, 28 December 2006
Patches we are tracking locally (until Skia is fixed upstream):
fix_for_1186198.diff -- eseidel, 6/4/08, BUG=1186198
linux_patch.diff
/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SkUserConfig_DEFINED
#define SkUserConfig_DEFINED
/* SkTypes.h, the root of the public header files, does the following trick:
#include <SkPreConfig.h>
#include <SkUserConfig.h>
#include <SkPostConfig.h>
SkPreConfig.h runs first, and it is responsible for initializing certain
skia defines.
SkPostConfig.h runs last, and its job is to just check that the final
defines are consistent (i.e. that we don't have mutually conflicting
defines).
SkUserConfig.h (this file) runs in the middle. It gets to change or augment
the list of flags initially set in preconfig, and then postconfig checks
that everything still makes sense.
Below are optional defines that add, subtract, or change default behavior
in Skia. Your port can locally edit this file to enable/disable flags as
you choose, or these can be delared on your command line (i.e. -Dfoo).
By default, this include file will always default to having all of the flags
commented out, so including it will have no effect.
*/
///////////////////////////////////////////////////////////////////////////////
/* 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
/* Somewhat independent of how SkScalar is implemented, Skia also wants to know
if it can use floats at all. Naturally, if SK_SCALAR_IS_FLOAT is defined,
then so muse SK_CAN_USE_FLOAT, but if scalars are fixed, SK_CAN_USE_FLOAT
can go either way.
*/
//#define SK_CAN_USE_FLOAT
/* 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
during development, but will slow things down in a shipping product.
By default, these mutually exclusive flags are defined in SkPreConfig.h,
based on the presence or absence of NDEBUG, but that decision can be changed
here.
*/
//#define SK_DEBUG
//#define SK_RELEASE
/* 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
SkPostConfig.h to write to an illegal address
*/
//#define SK_CRASH() *(int *)(uintptr_t)0 = 0
/* preconfig will have attempted to determine the endianness of the system,
but you can change these mutually exclusive flags here.
*/
//#define SK_CPU_BENDIAN
//#define SK_CPU_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
/* Some envorinments do not suport writable globals (eek!). If yours does not,
define this flag.
*/
//#define SK_USE_RUNTIME_GLOBALS
/* If zlib is available and you want to support the flate compression
algorithm (used in PDF generation), define SK_ZLIB_INCLUDE to be the
include path.
*/
//#define SK_ZLIB_INCLUDE <zlib.h>
#define SK_ZLIB_INCLUDE "third_party/zlib/zlib.h"
/* Define this to allow PDF scalars above 32k. The PDF/A spec doesn't allow
them, but modern PDF interpreters should handle them just fine.
*/
//#define SK_ALLOW_LARGE_PDF_SCALARS
/* Define this to provide font subsetter for font subsetting when generating
PDF documents.
*/
#define SK_SFNTLY_SUBSETTER \
"third_party/sfntly/cpp/src/sample/chromium/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 write debug messages to a console, skia will call SkDebugf(...) following
printf conventions (e.g. const char* format, ...). If you want to redirect
this to something other than printf, define yours here
*/
//#define SkDebugf(...) MyFunction(__VA_ARGS__)
/* If SK_DEBUG is defined, then you can optionally define SK_SUPPORT_UNITTEST
which will run additional self-tests at startup. These can take a long time,
so this flag is optional.
*/
#ifdef SK_DEBUG
#define SK_SUPPORT_UNITTEST
#endif
/* If your system embeds skia and has complex event logging, define this
symbol to name a file that maps the following macros to your system's
equivalents:
SK_TRACE_EVENT0(event)
SK_TRACE_EVENT1(event, name1, value1)
SK_TRACE_EVENT2(event, name1, value1, name2, value2)
src/utils/SkDebugTrace.h has a trivial implementation that writes to
the debug output stream. If SK_USER_TRACE_INCLUDE_FILE is not defined,
SkTrace.h will define the above three macros to do nothing.
*/
#undef SK_USER_TRACE_INCLUDE_FILE
// ===== Begin Chrome-specific definitions =====
#define SK_SCALAR_IS_FLOAT
#undef SK_SCALAR_IS_FIXED
#define SK_MSCALAR_IS_DOUBLE
#undef SK_MSCALAR_IS_FLOAT
#define GR_MAX_OFFSCREEN_AA_DIM 512
// Log the file and line number for assertions.
#define SkDebugf(...) SkDebugf_FileLine(__FILE__, __LINE__, false, __VA_ARGS__)
SK_API void SkDebugf_FileLine(const char* file, int line, bool fatal,
const char* format, ...);
// Marking the debug print as "fatal" will cause a debug break, so we don't need
// a separate crash call here.
#define SK_DEBUGBREAK(cond) do { if (!(cond)) { \
SkDebugf_FileLine(__FILE__, __LINE__, true, \
"%s:%d: failed assertion \"%s\"\n", \
__FILE__, __LINE__, #cond); } } while (false)
#if !defined(ANDROID) // On Android, we use the skia default settings.
#define SK_A32_SHIFT 24
#define SK_R32_SHIFT 16
#define SK_G32_SHIFT 8
#define SK_B32_SHIFT 0
#endif
#if defined(SK_BUILD_FOR_WIN32)
#define SK_BUILD_FOR_WIN
// VC8 doesn't support stdint.h, so we define those types here.
#define SK_IGNORE_STDINT_DOT_H
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;
// VC doesn't support __restrict__, so make it a NOP.
#undef SK_RESTRICT
#define SK_RESTRICT
// Skia uses this deprecated bzero function to fill zeros into a string.
#define bzero(str, len) memset(str, 0, len)
#elif defined(SK_BUILD_FOR_MAC)
#define SK_CPU_LENDIAN
#undef SK_CPU_BENDIAN
#elif defined(SK_BUILD_FOR_UNIX)
// Prefer FreeType's emboldening algorithm to Skia's
// TODO: skia used to just use hairline, but has improved since then, so
// we should revisit this choice...
#define SK_USE_FREETYPE_EMBOLDEN
#ifdef SK_CPU_BENDIAN
// Above we set the order for ARGB channels in registers. I suspect that, on
// big endian machines, you can keep this the same and everything will work.
// The in-memory order will be different, of course, but as long as everything
// is reading memory as words rather than bytes, it will all work. However, if
// you find that colours are messed up I thought that I would leave a helpful
// locator for you. Also see the comments in
// base/gfx/bitmap_platform_device_linux.h
#error Read the comment at this location
#endif
#endif
// The default crash macro writes to badbeef which can cause some strange
// problems. Instead, pipe this through to the logging function as a fatal
// assertion.
#define SK_CRASH() SkDebugf_FileLine(__FILE__, __LINE__, true, "SK_CRASH")
// Uncomment the following line to forward skia trace events to Chrome
// tracing.
// #define SK_USER_TRACE_INCLUDE_FILE "skia/ext/skia_trace_shim.h"
// ===== End Chrome-specific definitions =====
#endif
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <stdio.h>
#include <stdlib.h>
#include <new>
#include "base/process_util.h"
#include "third_party/skia/include/core/SkTypes.h"
#include "third_party/skia/include/core/SkThread.h"
// This implementation of sk_malloc_flags() and friends is identical
// to SkMemory_malloc.c, except that it disables the CRT's new_handler
// during malloc(), when SK_MALLOC_THROW is not set (ie., when
// sk_malloc_flags() would not abort on NULL).
SK_DECLARE_STATIC_MUTEX(gSkNewHandlerMutex);
void sk_throw() {
SkASSERT(!"sk_throw");
abort();
}
void sk_out_of_memory(void) {
SkASSERT(!"sk_out_of_memory");
abort();
}
void* sk_malloc_throw(size_t size) {
return sk_malloc_flags(size, SK_MALLOC_THROW);
}
void* sk_realloc_throw(void* addr, size_t size) {
void* p = realloc(addr, size);
if (size == 0) {
return p;
}
if (p == NULL) {
sk_throw();
}
return p;
}
void sk_free(void* p) {
if (p) {
free(p);
}
}
void* sk_malloc_flags(size_t size, unsigned flags) {
void* p;
#if defined(ANDROID)
// Android doesn't have std::set_new_handler.
p = malloc(size);
#else
if (!(flags & SK_MALLOC_THROW)) {
#if defined(OS_MACOSX) && !defined(OS_IOS)
p = base::UncheckedMalloc(size);
#else
SkAutoMutexAcquire lock(gSkNewHandlerMutex);
std::new_handler old_handler = std::set_new_handler(NULL);
p = malloc(size);
std::set_new_handler(old_handler);
#endif
} else {
p = malloc(size);
}
#endif
if (p == NULL) {
if (flags & SK_MALLOC_THROW) {
sk_throw();
}
}
return p;
}
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/skia/include/core/SkThread.h"
#include <new>
#include "base/atomicops.h"
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/synchronization/lock.h"
/** Adds one to the int specified by the address (in a thread-safe manner), and
returns the previous value.
No additional memory barrier is required.
This must act as a compiler barrier.
*/
int32_t sk_atomic_inc(int32_t* addr) {
// sk_atomic_inc is expected to return the old value,
// Barrier_AtomicIncrement returns the new value.
return base::subtle::NoBarrier_AtomicIncrement(addr, 1) - 1;
}
/* Subtracts one from the int specified by the address (in a thread-safe
manner), and returns the previous value.
Expected to act as a release (SL/S) memory barrier and a compiler barrier.
*/
int32_t sk_atomic_dec(int32_t* addr) {
// sk_atomic_dec is expected to return the old value,
// Barrier_AtomicIncrement returns the new value.
return base::subtle::Barrier_AtomicIncrement(addr, -1) + 1;
}
/** If sk_atomic_dec does not act as an aquire (L/SL) barrier, this is expected
to act as an aquire (L/SL) memory barrier and as a compiler barrier.
*/
void sk_membar_aquire__after_atomic_dec() { }
/** Adds one to the int specified by the address iff the int specified by the
address is not zero (in a thread-safe manner), and returns the previous
value.
No additional memory barrier is required.
This must act as a compiler barrier.
*/
int32_t sk_atomic_conditional_inc(int32_t* addr) {
int32_t value = *addr;
while (true) {
if (value == 0) {
return 0;
}
int32_t before;
before = base::subtle::Acquire_CompareAndSwap(addr, value, value + 1);
if (before == value) {
return value;
} else {
value = before;
}
}
}
/** If sk_atomic_conditional_inc does not act as an aquire (L/SL) barrier, this
is expected to act as an aquire (L/SL) memory barrier and as a compiler
barrier.
*/
void sk_membar_aquire__after_atomic_conditional_inc() { }
SkMutex::SkMutex() {
COMPILE_ASSERT(sizeof(base::Lock) <= sizeof(fStorage), Lock_is_too_big_for_SkMutex);
base::Lock* lock = reinterpret_cast<base::Lock*>(fStorage);
new(lock) base::Lock();
}
SkMutex::~SkMutex() {
base::Lock* lock = reinterpret_cast<base::Lock*>(fStorage);
lock->~Lock();
}
void SkMutex::acquire() {
base::Lock* lock = reinterpret_cast<base::Lock*>(fStorage);
lock->Acquire();
}
void SkMutex::release() {
base::Lock* lock = reinterpret_cast<base::Lock*>(fStorage);
lock->Release();
}
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "SkTypeface.h"
// ===== Begin Chrome-specific definitions =====
uint32_t SkTypeface::UniqueID(const SkTypeface* face)
{
return 0;
}
void SkTypeface::serialize(SkWStream* stream) const {
}
SkTypeface* SkTypeface::Deserialize(SkStream* stream) {
return NULL;
}
// ===== End Chrome-specific definitions =====
This diff is collapsed.
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SKIA_EXT_ANALYSIS_CANVAS_H_
#define SKIA_EXT_ANALYSIS_CANVAS_H_
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkDevice.h"
namespace skia {
class AnalysisDevice;
// Does not render anything, but gathers statistics about a region
// (specified as a clip rectangle) of an SkPicture as the picture is
// played back through it.
// To use: create a SkBitmap with kNo_Config, create an AnalysisDevice
// using that bitmap, and create an AnalysisCanvas using the device.
// Play a picture into the canvas, and then check result.
class SK_API AnalysisCanvas : public SkCanvas {
public:
AnalysisCanvas(AnalysisDevice*);
virtual ~AnalysisCanvas();
// Returns true when a SkColor can be used to represent result.
bool getColorIfSolid(SkColor* color) const;
bool hasText() const;
virtual bool clipRect(const SkRect& rect,
SkRegion::Op op = SkRegion::kIntersect_Op,
bool doAntiAlias = false) OVERRIDE;
virtual bool clipPath(const SkPath& path,
SkRegion::Op op = SkRegion::kIntersect_Op,
bool doAntiAlias = false) OVERRIDE;
virtual bool clipRRect(const SkRRect& rrect,
SkRegion::Op op = SkRegion::kIntersect_Op,
bool doAntiAlias = false) OVERRIDE;
virtual int saveLayer(const SkRect* bounds, const SkPaint*,
SkCanvas::SaveFlags flags) OVERRIDE;
virtual int save(SaveFlags flags = kMatrixClip_SaveFlag) OVERRIDE;
virtual void restore() OVERRIDE;
private:
typedef SkCanvas INHERITED;
static const int kNoLayer;
int savedStackSize_;
int forceNotSolidStackLevel_;
int forceNotTransparentStackLevel_;
};
class SK_API AnalysisDevice : public SkDevice {
public:
AnalysisDevice(const SkBitmap& bm);
virtual ~AnalysisDevice();
bool getColorIfSolid(SkColor* color) const;
bool hasText() const;
void setForceNotSolid(bool flag);
void setForceNotTransparent(bool flag);
protected:
virtual void clear(SkColor color) OVERRIDE;
virtual void drawPaint(const SkDraw&, const SkPaint& paint) OVERRIDE;
virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode,
size_t count, const SkPoint[],
const SkPaint& paint) OVERRIDE;
virtual void drawRect(const SkDraw&, const SkRect& r,
const SkPaint& paint) OVERRIDE;
virtual void drawOval(const SkDraw&, const SkRect& oval,
const SkPaint& paint) OVERRIDE;
virtual void drawPath(const SkDraw&, const SkPath& path,
const SkPaint& paint,
const SkMatrix* prePathMatrix = NULL,
bool pathIsMutable = false) OVERRIDE;
virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
const SkIRect* srcRectOrNull,
const SkMatrix& matrix, const SkPaint& paint)
OVERRIDE;
virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
int x, int y, const SkPaint& paint) OVERRIDE;
virtual void drawBitmapRect(const SkDraw&, const SkBitmap&,
const SkRect* srcOrNull, const SkRect& dst,
const SkPaint& paint) OVERRIDE;
virtual void drawText(const SkDraw&, const void* text, size_t len,
SkScalar x, SkScalar y, const SkPaint& paint)
OVERRIDE;
virtual void drawPosText(const SkDraw& draw, const void* text, size_t len,
const SkScalar pos[], SkScalar constY,
int scalarsPerPos, const SkPaint& paint) OVERRIDE;
virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
const SkPath& path, const SkMatrix* matrix,
const SkPaint& paint) OVERRIDE;
#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)
OVERRIDE;
#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) OVERRIDE;
virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
const SkPaint&) OVERRIDE;
private:
typedef SkDevice INHERITED;
bool isForcedNotSolid_;
bool isForcedNotTransparent_;
bool isSolidColor_;
SkColor color_;
bool isTransparent_;
bool hasText_;
};
} // namespace skia
#endif // SKIA_EXT_ANALYSIS_CANVAS_H_
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SKIA_EXT_BITMAP_PLATFORM_DEVICE_H_
#define SKIA_EXT_BITMAP_PLATFORM_DEVICE_H_
// This file provides an easy way to include the appropriate
// BitmapPlatformDevice header file for your platform.
#if defined(WIN32)
#include "skia/ext/bitmap_platform_device_win.h"
#elif defined(__APPLE__)
#include "skia/ext/bitmap_platform_device_mac.h"
#elif defined(ANDROID)
#include "skia/ext/bitmap_platform_device_android.h"
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun)
#include "skia/ext/bitmap_platform_device_linux.h"
#endif
namespace skia {
// Returns true if it is unsafe to attempt to allocate an offscreen buffer
// given these dimensions.
inline bool RasterDeviceTooBigToAllocate(int width, int height) {
#ifndef SKIA_EXT_RASTER_DEVICE_ALLOCATION_MAX
#define SKIA_EXT_RASTER_DEVICE_ALLOCATION_MAX (2 * 256 * 1024 * 1024)
#endif
int bytesPerPixel = 4;
int64_t bytes = (int64_t)width * height * bytesPerPixel;
return bytes > SKIA_EXT_RASTER_DEVICE_ALLOCATION_MAX;
}
}
#endif // SKIA_EXT_BITMAP_PLATFORM_DEVICE_H_
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "skia/ext/bitmap_platform_device_android.h"
#include "skia/ext/platform_canvas.h"
namespace skia {
BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height,
bool is_opaque) {
SkBitmap bitmap;
bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
if (bitmap.allocPixels()) {
bitmap.setIsOpaque(is_opaque);
// Follow the logic in SkCanvas::createDevice(), initialize the bitmap if it
// is not opaque.
if (!is_opaque)
bitmap.eraseARGB(0, 0, 0, 0);
return new BitmapPlatformDevice(bitmap);
}
return NULL;
}
BitmapPlatformDevice* BitmapPlatformDevice::CreateAndClear(int width,
int height,
bool is_opaque) {
BitmapPlatformDevice* device = Create(width, height, is_opaque);
if (!is_opaque)
device->accessBitmap(true).eraseARGB(0, 0, 0, 0);
return device;
}
BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height,
bool is_opaque,
uint8_t* data) {
SkBitmap bitmap;
bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
if (data)
bitmap.setPixels(data);
else if (!bitmap.allocPixels())
return NULL;
bitmap.setIsOpaque(is_opaque);
return new BitmapPlatformDevice(bitmap);
}
BitmapPlatformDevice::BitmapPlatformDevice(const SkBitmap& bitmap)
: SkDevice(bitmap) {
SetPlatformDevice(this, this);
}
BitmapPlatformDevice::~BitmapPlatformDevice() {
}
SkDevice* BitmapPlatformDevice::onCreateCompatibleDevice(
SkBitmap::Config config, int width, int height, bool isOpaque,
Usage /*usage*/) {
SkASSERT(config == SkBitmap::kARGB_8888_Config);
return BitmapPlatformDevice::Create(width, height, isOpaque);
}
PlatformSurface BitmapPlatformDevice::BeginPlatformPaint() {
// TODO(zhenghao): What should we return? The ptr to the address of the
// pixels? Maybe this won't be called at all.
return accessBitmap(true).getPixels();
}
void BitmapPlatformDevice::DrawToNativeContext(
PlatformSurface surface, int x, int y, const PlatformRect* src_rect) {
// Should never be called on Android.
SkASSERT(false);
}
// PlatformCanvas impl
SkCanvas* CreatePlatformCanvas(int width, int height, bool is_opaque,
uint8_t* data, OnFailureType failureType) {
skia::RefPtr<SkDevice> dev = skia::AdoptRef(
BitmapPlatformDevice::Create(width, height, is_opaque, data));
return CreateCanvas(dev, failureType);
}
// Port of PlatformBitmap to android
PlatformBitmap::~PlatformBitmap() {
// Nothing to do.
}
bool PlatformBitmap::Allocate(int width, int height, bool is_opaque) {
bitmap_.setConfig(SkBitmap::kARGB_8888_Config, width, height);
if (!bitmap_.allocPixels())
return false;
bitmap_.setIsOpaque(is_opaque);
surface_ = bitmap_.getPixels();
return true;
}
} // namespace skia
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SKIA_EXT_BITMAP_PLATFORM_DEVICE_ANDROID_H_
#define SKIA_EXT_BITMAP_PLATFORM_DEVICE_ANDROID_H_
#include "base/memory/ref_counted.h"
#include "base/compiler_specific.h"
#include "skia/ext/platform_device.h"
namespace skia {
// -----------------------------------------------------------------------------
// For now we just use SkBitmap for SkDevice
//
// This is all quite ok for test_shell. In the future we will want to use
// shared memory between the renderer and the main process at least. In this
// case we'll probably create the buffer from a precreated region of memory.
// -----------------------------------------------------------------------------
class BitmapPlatformDevice : public SkDevice, public PlatformDevice {
public:
// Construct a BitmapPlatformDevice. |is_opaque| should be set if the caller
// knows the bitmap will be completely opaque and allows some optimizations.
// The bitmap is not initialized.
static BitmapPlatformDevice* Create(int width, int height, bool is_opaque);
// Construct a BitmapPlatformDevice, as above.
// If |is_opaque| is false, the bitmap is initialized to 0.
static BitmapPlatformDevice* CreateAndClear(int width, int height,
bool is_opaque);
// This doesn't take ownership of |data|. If |data| is null, the bitmap
// is not initialized to 0.
static BitmapPlatformDevice* Create(int width, int height, bool is_opaque,
uint8_t* data);
// Create a BitmapPlatformDevice from an already constructed bitmap;
// you should probably be using Create(). This may become private later if
// we ever have to share state between some native drawing UI and Skia, like
// the Windows and Mac versions of this class do.
explicit BitmapPlatformDevice(const SkBitmap& other);
virtual ~BitmapPlatformDevice();
virtual PlatformSurface BeginPlatformPaint() OVERRIDE;
virtual void DrawToNativeContext(PlatformSurface surface, int x, int y,
const PlatformRect* src_rect) OVERRIDE;
protected:
virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config, int width,
int height, bool isOpaque,
Usage usage) OVERRIDE;
private:
DISALLOW_COPY_AND_ASSIGN(BitmapPlatformDevice);
};
} // namespace skia
#endif // SKIA_EXT_BITMAP_PLATFORM_DEVICE_ANDROID_H_
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SKIA_EXT_BITMAP_PLATFORM_DEVICE_DATA_H_
#define SKIA_EXT_BITMAP_PLATFORM_DEVICE_DATA_H_
#include "skia/ext/bitmap_platform_device.h"
namespace skia {
class BitmapPlatformDevice::BitmapPlatformDeviceData :
#if defined(WIN32) || defined(__APPLE__)
public SkRefCnt {
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun)
// These objects are reference counted and own a Cairo surface. The surface
// is the backing store for a Skia bitmap and we reference count it so that
// we can copy BitmapPlatformDevice objects without having to copy all the
// image data.
public base::RefCounted<BitmapPlatformDeviceData> {
#endif
public:
#if defined(WIN32)
typedef HBITMAP PlatformContext;
#elif defined(__APPLE__)
typedef CGContextRef PlatformContext;
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun)
typedef cairo_t* PlatformContext;
#endif
#if defined(WIN32) || defined(__APPLE__)
explicit BitmapPlatformDeviceData(PlatformContext bitmap);
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun)
explicit BitmapPlatformDeviceData(cairo_surface_t* surface);
#endif
#if defined(WIN32)
// Create/destroy hdc_, which is the memory DC for our bitmap data.
HDC GetBitmapDC();
void ReleaseBitmapDC();
bool IsBitmapDCCreated() const;
#endif
#if defined(__APPLE__)
void ReleaseBitmapContext();
#endif // defined(__APPLE__)
// Sets the transform and clip operations. This will not update the CGContext,
// but will mark the config as dirty. The next call of LoadConfig will
// pick up these changes.
void SetMatrixClip(const SkMatrix& transform, const SkRegion& region);
// Loads the current transform and clip into the context. Can be called even
// when |bitmap_context_| is NULL (will be a NOP).
void LoadConfig();
const SkMatrix& transform() const {
return transform_;
}
PlatformContext bitmap_context() {
return bitmap_context_;
}
private:
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun)
friend class base::RefCounted<BitmapPlatformDeviceData>;
#endif
virtual ~BitmapPlatformDeviceData();
// Lazily-created graphics context used to draw into the bitmap.
PlatformContext bitmap_context_;
#if defined(WIN32)
// Lazily-created DC used to draw into the bitmap, see GetBitmapDC().
HDC hdc_;
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__sun)
cairo_surface_t *const surface_;
#endif
// True when there is a transform or clip that has not been set to the
// context. The context is retrieved for every text operation, and the
// transform and clip do not change as much. We can save time by not loading
// the clip and transform for every one.
bool config_dirty_;
// Translation assigned to the context: we need to keep track of this
// separately so it can be updated even if the context isn't created yet.
SkMatrix transform_;
// The current clipping
SkRegion clip_region_;
// Disallow copy & assign.
BitmapPlatformDeviceData(const BitmapPlatformDeviceData&);
BitmapPlatformDeviceData& operator=(const BitmapPlatformDeviceData&);
};
} // namespace skia
#endif // SKIA_EXT_BITMAP_PLATFORM_DEVICE_DATA_H_
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "skia/ext/bitmap_platform_device_linux.h"
#include "skia/ext/bitmap_platform_device_data.h"
#include "skia/ext/platform_canvas.h"
#if defined(OS_OPENBSD)
#include <cairo.h>
#else
#include <cairo/cairo.h>
#endif
namespace skia {
namespace {
void LoadMatrixToContext(cairo_t* context, const SkMatrix& matrix) {
cairo_matrix_t cairo_matrix;
cairo_matrix_init(&cairo_matrix,
SkScalarToFloat(matrix.getScaleX()),
SkScalarToFloat(matrix.getSkewY()),
SkScalarToFloat(matrix.getSkewX()),
SkScalarToFloat(matrix.getScaleY()),
SkScalarToFloat(matrix.getTranslateX()),
SkScalarToFloat(matrix.getTranslateY()));
cairo_set_matrix(context, &cairo_matrix);
}
void LoadClipToContext(cairo_t* context, const SkRegion& clip) {
cairo_reset_clip(context);
// TODO(brettw) support non-rect clips.
SkIRect bounding = clip.getBounds();
cairo_rectangle(context, bounding.fLeft, bounding.fTop,
bounding.fRight - bounding.fLeft,
bounding.fBottom - bounding.fTop);
cairo_clip(context);
}
} // namespace
BitmapPlatformDevice::BitmapPlatformDeviceData::BitmapPlatformDeviceData(
cairo_surface_t* surface)
: surface_(surface),
config_dirty_(true),
transform_(SkMatrix::I()) { // Want to load the config next time.
bitmap_context_ = cairo_create(surface);
}
BitmapPlatformDevice::BitmapPlatformDeviceData::~BitmapPlatformDeviceData() {
cairo_destroy(bitmap_context_);
cairo_surface_destroy(surface_);
}
void BitmapPlatformDevice::BitmapPlatformDeviceData::SetMatrixClip(
const SkMatrix& transform,
const SkRegion& region) {
transform_ = transform;
clip_region_ = region;
config_dirty_ = true;
}
void BitmapPlatformDevice::BitmapPlatformDeviceData::LoadConfig() {
if (!config_dirty_ || !bitmap_context_)
return; // Nothing to do.
config_dirty_ = false;
// Load the identity matrix since this is what our clip is relative to.
cairo_matrix_t cairo_matrix;
cairo_matrix_init_identity(&cairo_matrix);
cairo_set_matrix(bitmap_context_, &cairo_matrix);
LoadClipToContext(bitmap_context_, clip_region_);
LoadMatrixToContext(bitmap_context_, transform_);
}
// We use this static factory function instead of the regular constructor so
// that we can create the pixel data before calling the constructor. This is
// required so that we can call the base class' constructor with the pixel
// data.
BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height,
bool is_opaque,
cairo_surface_t* surface) {
if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
cairo_surface_destroy(surface);
return NULL;
}
SkBitmap bitmap;
bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height,
cairo_image_surface_get_stride(surface));
bitmap.setPixels(cairo_image_surface_get_data(surface));
bitmap.setIsOpaque(is_opaque);
// The device object will take ownership of the graphics context.
return new BitmapPlatformDevice
(bitmap, new BitmapPlatformDeviceData(surface));
}
BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height,
bool is_opaque) {
// This initializes the bitmap to all zeros.
cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
width, height);
BitmapPlatformDevice* device = Create(width, height, is_opaque, surface);
#ifndef NDEBUG
if (device && is_opaque) // Fill with bright bluish green
device->eraseColor(SkColorSetARGB(255, 0, 255, 128));
#endif
return device;
}
BitmapPlatformDevice* BitmapPlatformDevice::CreateAndClear(int width,
int height,
bool is_opaque) {
// The Linux port always constructs initialized bitmaps, so there is no extra
// work to perform here.
return Create(width, height, is_opaque);
}
BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height,
bool is_opaque,
uint8_t* data) {
cairo_surface_t* surface = cairo_image_surface_create_for_data(
data, CAIRO_FORMAT_ARGB32, width, height,
cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width));
return Create(width, height, is_opaque, surface);
}
// The device will own the bitmap, which corresponds to also owning the pixel
// data. Therefore, we do not transfer ownership to the SkDevice's bitmap.
BitmapPlatformDevice::BitmapPlatformDevice(
const SkBitmap& bitmap,
BitmapPlatformDeviceData* data)
: SkDevice(bitmap),
data_(data) {
SetPlatformDevice(this, this);
}
BitmapPlatformDevice::~BitmapPlatformDevice() {
}
SkDevice* BitmapPlatformDevice::onCreateCompatibleDevice(
SkBitmap::Config config, int width, int height, bool isOpaque,
Usage /*usage*/) {
SkASSERT(config == SkBitmap::kARGB_8888_Config);
return BitmapPlatformDevice::Create(width, height, isOpaque);
}
cairo_t* BitmapPlatformDevice::BeginPlatformPaint() {
data_->LoadConfig();
cairo_t* cairo = data_->bitmap_context();
cairo_surface_t* surface = cairo_get_target(cairo);
// Tell cairo to flush anything it has pending.
cairo_surface_flush(surface);
// Tell Cairo that we (probably) modified (actually, will modify) its pixel
// buffer directly.
cairo_surface_mark_dirty(surface);
return cairo;
}
void BitmapPlatformDevice::DrawToNativeContext(
PlatformSurface surface, int x, int y, const PlatformRect* src_rect) {
// Should never be called on Linux.
SkASSERT(false);
}
void BitmapPlatformDevice::setMatrixClip(const SkMatrix& transform,
const SkRegion& region,
const SkClipStack&) {
data_->SetMatrixClip(transform, region);
}
// PlatformCanvas impl
SkCanvas* CreatePlatformCanvas(int width, int height, bool is_opaque,
uint8_t* data, OnFailureType failureType) {
skia::RefPtr<SkDevice> dev = skia::AdoptRef(
BitmapPlatformDevice::Create(width, height, is_opaque, data));
return CreateCanvas(dev, failureType);
}
// Port of PlatformBitmap to linux
PlatformBitmap::~PlatformBitmap() {
cairo_destroy(surface_);
}
bool PlatformBitmap::Allocate(int width, int height, bool is_opaque) {
// The SkBitmap allocates and owns the bitmap memory; PlatformBitmap owns the
// cairo drawing context tied to the bitmap. The SkBitmap's pixelRef can
// outlive the PlatformBitmap if additional copies are made.
int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
bitmap_.setConfig(SkBitmap::kARGB_8888_Config, width, height, stride);
if (!bitmap_.allocPixels()) // Using the default allocator.
return false;
bitmap_.setIsOpaque(is_opaque);
cairo_surface_t* surf = cairo_image_surface_create_for_data(
reinterpret_cast<unsigned char*>(bitmap_.getPixels()),
CAIRO_FORMAT_ARGB32,
width,
height,
stride);
if (cairo_surface_status(surf) != CAIRO_STATUS_SUCCESS) {
cairo_surface_destroy(surf);
return false;
}
surface_ = cairo_create(surf);
cairo_surface_destroy(surf);
return true;
}
} // namespace skia
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SKIA_EXT_BITMAP_PLATFORM_DEVICE_LINUX_H_
#define SKIA_EXT_BITMAP_PLATFORM_DEVICE_LINUX_H_
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "skia/ext/platform_device.h"
typedef struct _cairo_surface cairo_surface_t;
// -----------------------------------------------------------------------------
// Image byte ordering on Linux:
//
// Pixels are packed into 32-bit words these days. Even for 24-bit images,
// often 8-bits will be left unused for alignment reasons. Thus, when you see
// ARGB as the byte order you have to wonder if that's in memory order or
// little-endian order. Here I'll write A.R.G.B to specifiy the memory order.
//
// GdkPixbuf's provide a nice backing store and defaults to R.G.B.A order.
// They'll do the needed byte swapping to match the X server when drawn.
//
// Skia can be controled in skia/include/corecg/SkUserConfig.h (see bits about
// SK_R32_SHIFT). For Linux we define it to be ARGB in registers. For little
// endian machines that means B.G.R.A in memory.
//
// The image loaders are controlled in
// webkit/port/platform/image-decoders/ImageDecoder.h (see setRGBA). These are
// also configured for ARGB in registers.
//
// Cairo's only 32-bit mode is ARGB in registers.
//
// X servers commonly have a 32-bit visual with xRGB in registers (since they
// typically don't do alpha blending of drawables at the user level. Composite
// extensions aside.)
//
// We don't use GdkPixbuf because its byte order differs from the rest. Most
// importantly, it differs from Cairo which, being a system library, is
// something that we can't easily change.
// -----------------------------------------------------------------------------
namespace skia {
// -----------------------------------------------------------------------------
// This is the Linux bitmap backing for Skia. We create a Cairo image surface
// to store the backing buffer. This buffer is BGRA in memory (on little-endian
// machines).
//
// For now we are also using Cairo to paint to the Drawables so we provide an
// accessor for getting the surface.
//
// This is all quite ok for test_shell. In the future we will want to use
// shared memory between the renderer and the main process at least. In this
// case we'll probably create the buffer from a precreated region of memory.
// -----------------------------------------------------------------------------
class BitmapPlatformDevice : public SkDevice, public PlatformDevice {
// A reference counted cairo surface
class BitmapPlatformDeviceData;
public:
// Create a BitmapPlatformDeviceLinux from an already constructed bitmap;
// you should probably be using Create(). This may become private later if
// we ever have to share state between some native drawing UI and Skia, like
// the Windows and Mac versions of this class do.
//
// This object takes ownership of @data.
BitmapPlatformDevice(const SkBitmap& other, BitmapPlatformDeviceData* data);
virtual ~BitmapPlatformDevice();
// Constructs a device with size |width| * |height| with contents initialized
// to zero. |is_opaque| should be set if the caller knows the bitmap will be
// completely opaque and allows some optimizations.
static BitmapPlatformDevice* Create(int width, int height, bool is_opaque);
// Performs the same construction as Create.
// Other ports require a separate construction routine because Create does not
// initialize the bitmap to 0.
static BitmapPlatformDevice* CreateAndClear(int width, int height,
bool is_opaque);
// This doesn't take ownership of |data|. If |data| is NULL, the contents
// of the device are initialized to 0.
static BitmapPlatformDevice* Create(int width, int height, bool is_opaque,
uint8_t* data);
// Overridden from SkDevice:
virtual void setMatrixClip(const SkMatrix& transform, const SkRegion& region,
const SkClipStack&) OVERRIDE;
// Overridden from PlatformDevice:
virtual cairo_t* BeginPlatformPaint() OVERRIDE;
virtual void DrawToNativeContext(PlatformSurface surface, int x, int y,
const PlatformRect* src_rect) OVERRIDE;
protected:
virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config, int width,
int height, bool isOpaque,
Usage usage) OVERRIDE;
private:
static BitmapPlatformDevice* Create(int width, int height, bool is_opaque,
cairo_surface_t* surface);
scoped_refptr<BitmapPlatformDeviceData> data_;
DISALLOW_COPY_AND_ASSIGN(BitmapPlatformDevice);
};
} // namespace skia
#endif // SKIA_EXT_BITMAP_PLATFORM_DEVICE_LINUX_H_
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SKIA_EXT_BITMAP_PLATFORM_DEVICE_MAC_H_
#define SKIA_EXT_BITMAP_PLATFORM_DEVICE_MAC_H_
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "skia/ext/platform_device.h"
#include "skia/ext/refptr.h"
namespace skia {
// A device is basically a wrapper around SkBitmap that provides a surface for
// SkCanvas to draw into. Our device provides a surface CoreGraphics can also
// write to. BitmapPlatformDevice creates a bitmap using
// CGCreateBitmapContext() in a format that Skia supports and can then use this
// to draw text into, etc. This pixel data is provided to the bitmap that the
// device contains so that it can be shared.
//
// The device owns the pixel data, when the device goes away, the pixel data
// also becomes invalid. THIS IS DIFFERENT THAN NORMAL SKIA which uses
// reference counting for the pixel data. In normal Skia, you could assign
// another bitmap to this device's bitmap and everything will work properly.
// For us, that other bitmap will become invalid as soon as the device becomes
// invalid, which may lead to subtle bugs. Therefore, DO NOT ASSIGN THE
// DEVICE'S PIXEL DATA TO ANOTHER BITMAP, make sure you copy instead.
class SK_API BitmapPlatformDevice : public SkDevice, public PlatformDevice {
public:
// Creates a BitmapPlatformDevice instance. |is_opaque| should be set if the
// caller knows the bitmap will be completely opaque and allows some
// optimizations.
// |context| may be NULL. If |context| is NULL, then the bitmap backing store
// is not initialized.
static BitmapPlatformDevice* Create(CGContextRef context,
int width, int height,
bool is_opaque);
// Creates a BitmapPlatformDevice instance. If |is_opaque| is false,
// then the bitmap is initialzed to 0.
static BitmapPlatformDevice* CreateAndClear(int width, int height,
bool is_opaque);
// Creates a context for |data| and calls Create.
// If |data| is NULL, then the bitmap backing store is not initialized.
static BitmapPlatformDevice* CreateWithData(uint8_t* data,
int width, int height,
bool is_opaque);
virtual ~BitmapPlatformDevice();
// PlatformDevice overrides
virtual CGContextRef GetBitmapContext() OVERRIDE;
virtual void DrawToNativeContext(CGContextRef context, int x, int y,
const CGRect* src_rect) OVERRIDE;
// SkDevice overrides
virtual void setMatrixClip(const SkMatrix& transform, const SkRegion& region,
const SkClipStack&) OVERRIDE;
protected:
// Reference counted data that can be shared between multiple devices. This
// allows copy constructors and operator= for devices to work properly. The
// bitmaps used by the base device class are already refcounted and copyable.
class BitmapPlatformDeviceData;
BitmapPlatformDevice(const skia::RefPtr<BitmapPlatformDeviceData>& data,
const SkBitmap& bitmap);
// Flushes the CoreGraphics context so that the pixel data can be accessed
// directly by Skia. Overridden from SkDevice, this is called when Skia
// starts accessing pixel data.
virtual const SkBitmap& onAccessBitmap(SkBitmap*) OVERRIDE;
virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config, int width,
int height, bool isOpaque,
Usage usage) OVERRIDE;
// Data associated with this device, guaranteed non-null.
skia::RefPtr<BitmapPlatformDeviceData> data_;
DISALLOW_COPY_AND_ASSIGN(BitmapPlatformDevice);
};
} // namespace skia
#endif // SKIA_EXT_BITMAP_PLATFORM_DEVICE_MAC_H_
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "skia/ext/bitmap_platform_device_mac.h"
#include "base/memory/scoped_ptr.h"
#include "skia/ext/skia_utils_mac.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkMatrix.h"
#include "third_party/skia/include/core/SkRegion.h"
#include "third_party/skia/include/core/SkClipStack.h"
namespace skia {
const int kWidth = 400;
const int kHeight = 300;
class BitmapPlatformDeviceMacTest : public testing::Test {
public:
BitmapPlatformDeviceMacTest() {
bitmap_.reset(BitmapPlatformDevice::Create(
NULL, kWidth, kHeight, /*is_opaque=*/true));
}
scoped_ptr<BitmapPlatformDevice> bitmap_;
};
TEST_F(BitmapPlatformDeviceMacTest, ClipRectTransformWithTranslate) {
SkMatrix transform;
transform.setTranslate(50, 140);
SkClipStack ignore;
SkRegion clip_region;
SkIRect rect;
rect.set(0, 0, kWidth, kHeight);
clip_region.setRect(rect);
bitmap_->setMatrixClip(transform, clip_region, ignore);
CGContextRef context = bitmap_->GetBitmapContext();
SkRect clip_rect = gfx::CGRectToSkRect(CGContextGetClipBoundingBox(context));
transform.mapRect(&clip_rect);
EXPECT_EQ(0, clip_rect.fLeft);
EXPECT_EQ(0, clip_rect.fTop);
EXPECT_EQ(kWidth, clip_rect.width());
EXPECT_EQ(kHeight, clip_rect.height());
}
TEST_F(BitmapPlatformDeviceMacTest, ClipRectTransformWithScale) {
SkMatrix transform;
transform.setScale(0.5, 0.5);
SkClipStack unused;
SkRegion clip_region;
SkIRect rect;
rect.set(0, 0, kWidth, kHeight);
clip_region.setRect(rect);
bitmap_->setMatrixClip(transform, clip_region, unused);
CGContextRef context = bitmap_->GetBitmapContext();
SkRect clip_rect = gfx::CGRectToSkRect(CGContextGetClipBoundingBox(context));
transform.mapRect(&clip_rect);
EXPECT_EQ(0, clip_rect.fLeft);
EXPECT_EQ(0, clip_rect.fTop);
EXPECT_EQ(kWidth, clip_rect.width());
EXPECT_EQ(kHeight, clip_rect.height());
}
} // namespace skia
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SKIA_EXT_BITMAP_PLATFORM_DEVICE_WIN_H_
#define SKIA_EXT_BITMAP_PLATFORM_DEVICE_WIN_H_
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "skia/ext/platform_device.h"
#include "skia/ext/refptr.h"
namespace skia {
// A device is basically a wrapper around SkBitmap that provides a surface for
// SkCanvas to draw into. Our device provides a surface Windows can also write
// to. BitmapPlatformDevice creates a bitmap using CreateDIBSection() in a
// format that Skia supports and can then use this to draw ClearType into, etc.
// This pixel data is provided to the bitmap that the device contains so that it
// can be shared.
//
// The device owns the pixel data, when the device goes away, the pixel data
// also becomes invalid. THIS IS DIFFERENT THAN NORMAL SKIA which uses
// reference counting for the pixel data. In normal Skia, you could assign
// another bitmap to this device's bitmap and everything will work properly.
// For us, that other bitmap will become invalid as soon as the device becomes
// invalid, which may lead to subtle bugs. Therefore, DO NOT ASSIGN THE
// DEVICE'S PIXEL DATA TO ANOTHER BITMAP, make sure you copy instead.
class SK_API BitmapPlatformDevice : public SkDevice, public PlatformDevice {
public:
// Factory function. is_opaque should be set if the caller knows the bitmap
// will be completely opaque and allows some optimizations.
//
// The |shared_section| parameter is optional (pass NULL for default
// behavior). If |shared_section| is non-null, then it must be a handle to a
// file-mapping object returned by CreateFileMapping. See CreateDIBSection
// for details. If |shared_section| is null, the bitmap backing store is not
// initialized.
static BitmapPlatformDevice* Create(int width, int height,
bool is_opaque, HANDLE shared_section);
// Create a BitmapPlatformDevice with no shared section. The bitmap is not
// initialized to 0.
static BitmapPlatformDevice* Create(int width, int height, bool is_opaque);
// Creates a BitmapPlatformDevice instance respecting the parameters as above.
// If |is_opaque| is false, then the bitmap is initialzed to 0.
static BitmapPlatformDevice* CreateAndClear(int width, int height,
bool is_opaque);
virtual ~BitmapPlatformDevice();
// PlatformDevice overrides
// Retrieves the bitmap DC, which is the memory DC for our bitmap data. The
// bitmap DC is lazy created.
virtual PlatformSurface BeginPlatformPaint() OVERRIDE;
virtual void EndPlatformPaint() OVERRIDE;
virtual void DrawToNativeContext(HDC dc, int x, int y,
const RECT* src_rect) OVERRIDE;
// Loads the given transform and clipping region into the HDC. This is
// overridden from SkDevice.
virtual void setMatrixClip(const SkMatrix& transform, const SkRegion& region,
const SkClipStack&) OVERRIDE;
protected:
// Flushes the Windows device context so that the pixel data can be accessed
// directly by Skia. Overridden from SkDevice, this is called when Skia
// starts accessing pixel data.
virtual const SkBitmap& onAccessBitmap(SkBitmap* bitmap) OVERRIDE;
virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config, int width,
int height, bool isOpaque,
Usage usage) OVERRIDE;
private:
// Reference counted data that can be shared between multiple devices. This
// allows copy constructors and operator= for devices to work properly. The
// bitmaps used by the base device class are already refcounted and copyable.
class BitmapPlatformDeviceData;
// Private constructor.
BitmapPlatformDevice(const skia::RefPtr<BitmapPlatformDeviceData>& data,
const SkBitmap& bitmap);
// Data associated with this device, guaranteed non-null.
skia::RefPtr<BitmapPlatformDeviceData> data_;
#ifdef SK_DEBUG
int begin_paint_count_;
#endif
DISALLOW_COPY_AND_ASSIGN(BitmapPlatformDevice);
};
} // namespace skia
#endif // SKIA_EXT_BITMAP_PLATFORM_DEVICE_WIN_H_
This diff is collapsed.
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SKIA_EXT_CONVOLVER_H_
#define SKIA_EXT_CONVOLVER_H_
#include <cmath>
#include <vector>
#include "base/basictypes.h"
#include "base/cpu.h"
#include "third_party/skia/include/core/SkSize.h"
#include "third_party/skia/include/core/SkTypes.h"
// We can build SSE2 optimized versions for all x86 CPUs
// except when building for the IOS emulator.
#if defined(ARCH_CPU_X86_FAMILY) && !defined(OS_IOS)
#define SIMD_SSE2 1
#define SIMD_PADDING 8 // 8 * int16
#endif
// avoid confusion with Mac OS X's math library (Carbon)
#if defined(__APPLE__)
#undef FloatToFixed
#undef FixedToFloat
#endif
namespace skia {
// Represents a filter in one dimension. Each output pixel has one entry in this
// object for the filter values contributing to it. You build up the filter
// list by calling AddFilter for each output pixel (in order).
//
// We do 2-dimensional convolution by first convolving each row by one
// ConvolutionFilter1D, then convolving each column by another one.
//
// Entries are stored in fixed point, shifted left by kShiftBits.
class ConvolutionFilter1D {
public:
typedef short Fixed;
// The number of bits that fixed point values are shifted by.
enum { kShiftBits = 14 };
SK_API ConvolutionFilter1D();
SK_API ~ConvolutionFilter1D();
// Convert between floating point and our fixed point representation.
static Fixed FloatToFixed(float f) {
return static_cast<Fixed>(f * (1 << kShiftBits));
}
static unsigned char FixedToChar(Fixed x) {
return static_cast<unsigned char>(x >> kShiftBits);
}
static float FixedToFloat(Fixed x) {
// The cast relies on Fixed being a short, implying that on
// the platforms we care about all (16) bits will fit into
// the mantissa of a (32-bit) float.
COMPILE_ASSERT(sizeof(Fixed) == 2, fixed_type_should_fit_in_float_mantissa);
float raw = static_cast<float>(x);
return ldexpf(raw, -kShiftBits);
}
// Returns the maximum pixel span of a filter.
int max_filter() const { return max_filter_; }
// Returns the number of filters in this filter. This is the dimension of the
// output image.
int num_values() const { return static_cast<int>(filters_.size()); }
// Appends the given list of scaling values for generating a given output
// pixel. |filter_offset| is the distance from the edge of the image to where
// the scaling factors start. The scaling factors apply to the source pixels
// starting from this position, and going for the next |filter_length| pixels.
//
// You will probably want to make sure your input is normalized (that is,
// all entries in |filter_values| sub to one) to prevent affecting the overall
// brighness of the image.
//
// The filter_length must be > 0.
//
// This version will automatically convert your input to fixed point.
SK_API void AddFilter(int filter_offset,
const float* filter_values,
int filter_length);
// Same as the above version, but the input is already fixed point.
void AddFilter(int filter_offset,
const Fixed* filter_values,
int filter_length);
// Retrieves a filter for the given |value_offset|, a position in the output
// image in the direction we're convolving. The offset and length of the
// filter values are put into the corresponding out arguments (see AddFilter
// above for what these mean), and a pointer to the first scaling factor is
// returned. There will be |filter_length| values in this array.
inline const Fixed* FilterForValue(int value_offset,
int* filter_offset,
int* filter_length) const {
const FilterInstance& filter = filters_[value_offset];
*filter_offset = filter.offset;
*filter_length = filter.trimmed_length;
if (filter.trimmed_length == 0) {
return NULL;
}
return &filter_values_[filter.data_location];
}
// Retrieves the filter for the offset 0, presumed to be the one and only.
// The offset and length of the filter values are put into the corresponding
// out arguments (see AddFilter). Note that |filter_legth| and
// |specified_filter_length| may be different if leading/trailing zeros of the
// original floating point form were clipped.
// There will be |filter_length| values in the return array.
// Returns NULL if the filter is 0-length (for instance when all floating
// point values passed to AddFilter were clipped to 0).
const Fixed* GetSingleFilter(int* specified_filter_length,
int* filter_offset,
int* filter_length) const;
inline void PaddingForSIMD() {
// Padding |padding_count| of more dummy coefficients after the coefficients
// of last filter to prevent SIMD instructions which load 8 or 16 bytes
// together to access invalid memory areas. We are not trying to align the
// coefficients right now due to the opaqueness of <vector> implementation.
// This has to be done after all |AddFilter| calls.
#ifdef SIMD_PADDING
for (int i = 0; i < SIMD_PADDING; ++i)
filter_values_.push_back(static_cast<Fixed>(0));
#endif
}
private:
struct FilterInstance {
// Offset within filter_values for this instance of the filter.
int data_location;
// Distance from the left of the filter to the center. IN PIXELS
int offset;
// Number of values in this filter instance.
int trimmed_length;
// Filter length as specified. Note that this may be different from
// 'trimmed_length' if leading/trailing zeros of the original floating
// point form were clipped differently on each tail.
int length;
};
// Stores the information for each filter added to this class.
std::vector<FilterInstance> filters_;
// We store all the filter values in this flat list, indexed by
// |FilterInstance.data_location| to avoid the mallocs required for storing
// each one separately.
std::vector<Fixed> filter_values_;
// The maximum size of any filter we've added.
int max_filter_;
};
// Does a two-dimensional convolution on the given source image.
//
// It is assumed the source pixel offsets referenced in the input filters
// reference only valid pixels, so the source image size is not required. Each
// row of the source image starts |source_byte_row_stride| after the previous
// one (this allows you to have rows with some padding at the end).
//
// The result will be put into the given output buffer. The destination image
// size will be xfilter.num_values() * yfilter.num_values() pixels. It will be
// in rows of exactly xfilter.num_values() * 4 bytes.
//
// |source_has_alpha| is a hint that allows us to avoid doing computations on
// the alpha channel if the image is opaque. If you don't know, set this to
// true and it will work properly, but setting this to false will be a few
// percent faster if you know the image is opaque.
//
// The layout in memory is assumed to be 4-bytes per pixel in B-G-R-A order
// (this is ARGB when loaded into 32-bit words on a little-endian machine).
SK_API void BGRAConvolve2D(const unsigned char* source_data,
int source_byte_row_stride,
bool source_has_alpha,
const ConvolutionFilter1D& xfilter,
const ConvolutionFilter1D& yfilter,
int output_byte_row_stride,
unsigned char* output,
bool use_simd_if_possible);
// Does a 1D convolution of the given source image along the X dimension on
// a single channel of the bitmap.
//
// The function uses the same convolution kernel for each pixel. That kernel
// must be added to |filter| at offset 0. This is a most straightforward
// implementation of convolution, intended chiefly for development purposes.
SK_API void SingleChannelConvolveX1D(const unsigned char* source_data,
int source_byte_row_stride,
int input_channel_index,
int input_channel_count,
const ConvolutionFilter1D& filter,
const SkISize& image_size,
unsigned char* output,
int output_byte_row_stride,
int output_channel_index,
int output_channel_count,
bool absolute_values);
// Does a 1D convolution of the given source image along the Y dimension on
// a single channel of the bitmap.
SK_API void SingleChannelConvolveY1D(const unsigned char* source_data,
int source_byte_row_stride,
int input_channel_index,
int input_channel_count,
const ConvolutionFilter1D& filter,
const SkISize& image_size,
unsigned char* output,
int output_byte_row_stride,
int output_channel_index,
int output_channel_count,
bool absolute_values);
} // namespace skia
#endif // SKIA_EXT_CONVOLVER_H_
This diff is collapsed.
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SKIA_EXT_CONVOLVER_SSE2_H_
#define SKIA_EXT_CONVOLVER_SSE2_H_
#include "skia/ext/convolver.h"
namespace skia {
void ConvolveVertically_SSE2(const ConvolutionFilter1D::Fixed* filter_values,
int filter_length,
unsigned char* const* source_data_rows,
int pixel_width,
unsigned char* out_row,
bool has_alpha);
void Convolve4RowsHorizontally_SSE2(const unsigned char* src_data[4],
const ConvolutionFilter1D& filter,
unsigned char* out_row[4]);
void ConvolveHorizontally_SSE2(const unsigned char* src_data,
const ConvolutionFilter1D& filter,
unsigned char* out_row);
} // namespace skia
#endif // SKIA_EXT_CONVOLVER_SSE2_H_
This diff is collapsed.
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This file provides integration with Google-style "base/logging.h" assertions
// for Skia SkASSERT. If you don't want this, you can link with another file
// that provides integration with the logging of your choice.
#include "base/logging.h"
#include "base/stringprintf.h"
#include "third_party/skia/include/core/SkTypes.h"
void SkDebugf_FileLine(const char* file, int line, bool fatal,
const char* format, ...) {
va_list ap;
va_start(ap, format);
std::string msg;
base::StringAppendV(&msg, format, ap);
va_end(ap);
logging::LogMessage(file, line,
fatal ? logging::LOG_FATAL : logging::LOG_INFO).stream()
<< msg;
}
This diff is collapsed.
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SKIA_EXT_IMAGE_OPERATIONS_H_
#define SKIA_EXT_IMAGE_OPERATIONS_H_
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkTypes.h"
struct SkIRect;
namespace skia {
class SK_API ImageOperations {
public:
enum ResizeMethod {
//
// Quality Methods
//
// Those enumeration values express a desired quality/speed tradeoff.
// They are translated into an algorithm-specific method that depends
// on the capabilities (CPU, GPU) of the underlying platform.
// It is possible for all three methods to be mapped to the same
// algorithm on a given platform.
// Good quality resizing. Fastest resizing with acceptable visual quality.
// This is typically intended for use during interactive layouts
// where slower platforms may want to trade image quality for large
// increase in resizing performance.
//
// For example the resizing implementation may devolve to linear
// filtering if this enables GPU acceleration to be used.
//
// Note that the underlying resizing method may be determined
// on the fly based on the parameters for a given resize call.
// For example an implementation using a GPU-based linear filter
// in the common case may still use a higher-quality software-based
// filter in cases where using the GPU would actually be slower - due
// to too much latency - or impossible - due to image format or size
// constraints.
RESIZE_GOOD,
// Medium quality resizing. Close to high quality resizing (better
// than linear interpolation) with potentially some quality being
// traded-off for additional speed compared to RESIZE_BEST.
//
// This is intended, for example, for generation of large thumbnails
// (hundreds of pixels in each dimension) from large sources, where
// a linear filter would produce too many artifacts but where
// a RESIZE_HIGH might be too costly time-wise.
RESIZE_BETTER,
// High quality resizing. The algorithm is picked to favor image quality.
RESIZE_BEST,
//
// Algorithm-specific enumerations
//
// Box filter. This is a weighted average of all of the pixels touching
// the destination pixel. For enlargement, this is nearest neighbor.
//
// You probably don't want this, it is here for testing since it is easy to
// compute. Use RESIZE_LANCZOS3 instead.
RESIZE_BOX,
// 1-cycle Hamming filter. This is tall is the middle and falls off towards
// the window edges but without going to 0. This is about 40% faster than
// a 2-cycle Lanczos.
RESIZE_HAMMING1,
// 2-cycle Lanczos filter. This is tall in the middle, goes negative on
// each side, then returns to zero. Does not provide as good a frequency
// response as a 3-cycle Lanczos but is roughly 30% faster.
RESIZE_LANCZOS2,
// 3-cycle Lanczos filter. This is tall in the middle, goes negative on
// each side, then oscillates 2 more times. It gives nice sharp edges.
RESIZE_LANCZOS3,
// Lanczos filter + subpixel interpolation. If subpixel rendering is not
// appropriate we automatically fall back to Lanczos.
RESIZE_SUBPIXEL,
// enum aliases for first and last methods by algorithm or by quality.
RESIZE_FIRST_QUALITY_METHOD = RESIZE_GOOD,
RESIZE_LAST_QUALITY_METHOD = RESIZE_BEST,
RESIZE_FIRST_ALGORITHM_METHOD = RESIZE_BOX,
RESIZE_LAST_ALGORITHM_METHOD = RESIZE_SUBPIXEL,
};
// Resizes the given source bitmap using the specified resize method, so that
// the entire image is (dest_size) big. The dest_subset is the rectangle in
// this destination image that should actually be returned.
//
// The output image will be (dest_subset.width(), dest_subset.height()). This
// will save work if you do not need the entire bitmap.
//
// The destination subset must be smaller than the destination image.
static SkBitmap Resize(const SkBitmap& source,
ResizeMethod method,
int dest_width, int dest_height,
const SkIRect& dest_subset,
SkBitmap::Allocator* allocator = NULL);
// Alternate version for resizing and returning the entire bitmap rather than
// a subset.
static SkBitmap Resize(const SkBitmap& source,
ResizeMethod method,
int dest_width, int dest_height,
SkBitmap::Allocator* allocator = NULL);
private:
ImageOperations(); // Class for scoping only.
// Supports all methods except RESIZE_SUBPIXEL.
static SkBitmap ResizeBasic(const SkBitmap& source,
ResizeMethod method,
int dest_width, int dest_height,
const SkIRect& dest_subset,
SkBitmap::Allocator* allocator = NULL);
// Subpixel renderer.
static SkBitmap ResizeSubpixel(const SkBitmap& source,
int dest_width, int dest_height,
const SkIRect& dest_subset,
SkBitmap::Allocator* allocator = NULL);
};
} // namespace skia
#endif // SKIA_EXT_IMAGE_OPERATIONS_H_
This diff is collapsed.
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "skia/ext/lazy_pixel_ref.h"
namespace skia {
LazyPixelRef::LazyPixelRef() : SkPixelRef(0) {
}
LazyPixelRef::~LazyPixelRef() {
}
} // namespace skia
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "skia/ext/platform_device.h"
namespace skia {
PlatformSurface PlatformDevice::BeginPlatformPaint() {
return NULL;
}
void PlatformDevice::EndPlatformPaint() {
// We don't need to do anything on Linux here.
}
} // namespace skia
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="ext">
<UniqueIdentifier>{3EE5B703-384C-67C2-8DE0-73108365DC85}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<None Include="skia.gyp"/>
<ClCompile Include="ext\image_operations_bench.cc">
<Filter>ext</Filter>
</ClCompile>
</ItemGroup>
</Project>
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment