Skia integration - preprocessing of shape geometry

This commit is contained in:
Viktor Chlumský 2020-10-17 13:12:23 +02:00
parent fe910c8b5a
commit 9d22335ea0
294 changed files with 51516 additions and 57 deletions

1
.gitattributes vendored
View File

@ -2,3 +2,4 @@
include/** linguist-vendored
lib/** linguist-vendored
freetype/** linguist-vendored
skia/** linguist-vendored

20
.gitignore vendored
View File

@ -1,11 +1,11 @@
Debug/
Release/
Release OpenMP/
Debug Library/
Release Library/
Release Library OpenMP/
x86/
x64/
/Debug/
/Release/
/Release OpenMP/
/Debug Library/
/Release Library/
/Release Library OpenMP/
/x86/
/x64/
.vs/
*.exe
*.zip
@ -17,9 +17,11 @@ x64/
*.suo
*.VC.opendb
*.VC.db
bin/*.lib
/bin/*.lib
output.png
render.png
out/
build/
build_xcode/
skia/win32/
skia/win64/

View File

@ -1,4 +1,23 @@
## Version 1.8 (2020-10-17)
- Integrated the Skia library into the project, which is used to preprocess the shape geometry and eliminate any self-intersections and other irregularities previously unsupported by the software
- The scanline pass and overlapping contour mode is made obsolete by this step and has been disabled by default. The preprocess step can be disabled by the new `-nopreprocess` switch and the former enabled by `-scanline` and `-overlap` respectively.
- The project can be built without the Skia library, forgoing the geometry preprocessing feature. This is controlled by the macro definition `MSDFGEN_USE_SKIA`
- Significantly improved performance of the core algorithm by reusing results from previously computed pixels
- Introduced an additional error correction routine which eliminates MSDF artifacts by analytically predicting results of bilinear interpolation
- Added the possibility to load font glyphs by their index rather than a Unicode value (use the prefix `g` before the character code in `-font` argument)
- Added `-distanceshift` argument that can be used to adjust the center of the distance range in the output distance field
- Fixed several errors in the evaluation of curve distances
- Fixed an issue with paths containing convergent corners (those whose inner angle is zero)
- The algorithm for pseudo-distance computation slightly changed, fixing certain rare edge cases and improving consistency
- Added the ability to supply own `FT_Face` handle to the msdfgen library
- Minor refactor of the core algorithm
### Version 1.7.1 (2020-03-09)
- Fixed an edge case bug in scanline rasterization
## Version 1.7 (2020-03-07)
- Added `mtsdf` mode - a combination of `msdf` with `sdf` in the alpha channel

View File

@ -1,9 +1,10 @@
cmake_minimum_required(VERSION 3.10)
project(msdfgen VERSION 1.7.1 LANGUAGES CXX)
project(msdfgen VERSION 1.8 LANGUAGES CXX)
option(MSDFGEN_BUILD_MSDFGEN_STANDALONE "Build the msdfgen standalone executable" ON)
option(MSDFGEN_USE_OPENMP "Build with OpenMP support for multithreaded code" OFF)
option(MSDFGEN_USE_CPP11 "Build with C++11 enabled" ON)
option(MSDFGEN_USE_SKIA "Build with the Skia library" OFF)
option(FREETYPE_WITH_PNG "Link libpng and zlib because FreeType is configured to require it" OFF)
option(FREETYPE_WITH_HARFBUZZ "Link HarfBuzz because FreeType is configured to require it" OFF)
@ -71,6 +72,12 @@ if(MSDFGEN_USE_OPENMP)
target_compile_definitions(msdfgen PRIVATE MSDFGEN_USE_OPENMP)
endif()
if(MSDFGEN_USE_SKIA)
find_package(Skia REQUIRED)
target_link_libraries(msdfgen-ext PRIVATE Skia::Skia)
target_compile_definitions(msdfgen-ext PUBLIC MSDFGEN_USE_SKIA)
endif()
add_library(msdfgen-ext ${msdfgen-ext_SOURCES} ${msdfgen-ext_PUBLIC_HEADERS} ${msdfgen-ext_PRIVATE_HEADERS} "./msdfgen-ext.h")
add_library(msdfgen::msdfgen-ext ALIAS msdfgen-ext)
set_target_properties(msdfgen-ext PROPERTIES

BIN
Msdfgen.aps Normal file

Binary file not shown.

Binary file not shown.

View File

@ -231,13 +231,13 @@
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>MSDFGEN_STANDALONE;MSDFGEN_USE_CPP11;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>MSDFGEN_USE_CPP11;MSDFGEN_USE_SKIA;MSDFGEN_STANDALONE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<AdditionalIncludeDirectories>include;freetype/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>include;freetype/include;skia/include;skia/include/core;skia/include/config;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<AdditionalLibraryDirectories>freetype/win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>freetype/win$(PlatformArchitecture);skia/win$(PlatformArchitecture)/debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Library|Win32'">
@ -245,9 +245,9 @@
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>MSDFGEN_USE_CPP11;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>MSDFGEN_USE_CPP11;MSDFGEN_USE_SKIA;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<AdditionalIncludeDirectories>include;freetype/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>include;freetype/include;skia/include;skia/include/core;skia/include/config;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -255,7 +255,7 @@
</Link>
<Lib>
<TargetMachine>MachineX86</TargetMachine>
<AdditionalLibraryDirectories>freetype/win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>freetype/win$(PlatformArchitecture);skia/win$(PlatformArchitecture)/debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Lib>
<ProjectReference />
</ItemDefinitionGroup>
@ -264,13 +264,13 @@
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>include;freetype/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>MSDFGEN_STANDALONE;MSDFGEN_USE_CPP11;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>include;freetype/include;skia/include;skia/include/core;skia/include/config;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>MSDFGEN_USE_CPP11;MSDFGEN_USE_SKIA;MSDFGEN_STANDALONE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<AdditionalLibraryDirectories>freetype/win64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>freetype/win$(PlatformArchitecture);skia/win$(PlatformArchitecture)/debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Library|x64'">
@ -278,12 +278,12 @@
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>MSDFGEN_USE_CPP11;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>include;freetype/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>MSDFGEN_USE_CPP11;MSDFGEN_USE_SKIA;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>include;freetype/include;skia/include;skia/include/core;skia/include/config;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Lib>
<AdditionalLibraryDirectories>freetype/win64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>freetype/win$(PlatformArchitecture);skia/win$(PlatformArchitecture)/debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@ -293,15 +293,15 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>MSDFGEN_STANDALONE;MSDFGEN_USE_CPP11;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>MSDFGEN_USE_CPP11;MSDFGEN_USE_SKIA;MSDFGEN_STANDALONE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>include;freetype/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>include;freetype/include;skia/include;skia/include/core;skia/include/config;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<SubSystem>Console</SubSystem>
<AdditionalLibraryDirectories>freetype/win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>freetype/win$(PlatformArchitecture);skia/win$(PlatformArchitecture)/release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>No</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
@ -312,16 +312,16 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>MSDFGEN_STANDALONE;MSDFGEN_USE_CPP11;MSDFGEN_USE_OPENMP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>MSDFGEN_USE_CPP11;MSDFGEN_USE_SKIA;MSDFGEN_USE_OPENMP;MSDFGEN_STANDALONE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>include;freetype/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>include;freetype/include;skia/include;skia/include/core;skia/include/config;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<OpenMPSupport>true</OpenMPSupport>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<SubSystem>Console</SubSystem>
<AdditionalLibraryDirectories>freetype/win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>freetype/win$(PlatformArchitecture);skia/win$(PlatformArchitecture)/release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>No</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
@ -332,9 +332,9 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>MSDFGEN_USE_CPP11;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>MSDFGEN_USE_CPP11;MSDFGEN_USE_SKIA;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>include;freetype/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>include;freetype/include;skia/include;skia/include/core;skia/include/config;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
@ -345,7 +345,7 @@
</Link>
<Lib>
<TargetMachine>MachineX86</TargetMachine>
<AdditionalLibraryDirectories>freetype/win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>freetype/win$(PlatformArchitecture);skia/win$(PlatformArchitecture)/release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Library OpenMP|Win32'">
@ -355,9 +355,9 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>MSDFGEN_USE_CPP11;MSDFGEN_USE_OPENMP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>MSDFGEN_USE_CPP11;MSDFGEN_USE_SKIA;MSDFGEN_USE_OPENMP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>include;freetype/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>include;freetype/include;skia/include;skia/include/core;skia/include/config;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<OpenMPSupport>true</OpenMPSupport>
</ClCompile>
<Link>
@ -369,7 +369,7 @@
</Link>
<Lib>
<TargetMachine>MachineX86</TargetMachine>
<AdditionalLibraryDirectories>freetype/win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>freetype/win$(PlatformArchitecture);skia/win$(PlatformArchitecture)/release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@ -379,15 +379,15 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>include;freetype/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>MSDFGEN_STANDALONE;MSDFGEN_USE_CPP11;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>include;freetype/include;skia/include;skia/include/core;skia/include/config;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>MSDFGEN_USE_CPP11;MSDFGEN_USE_SKIA;MSDFGEN_STANDALONE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<SubSystem>Console</SubSystem>
<AdditionalLibraryDirectories>freetype/win64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>freetype/win$(PlatformArchitecture);skia/win$(PlatformArchitecture)/release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>false</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
@ -398,8 +398,8 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>include;freetype/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>MSDFGEN_STANDALONE;MSDFGEN_USE_CPP11;MSDFGEN_USE_OPENMP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>include;freetype/include;skia/include;skia/include/core;skia/include/config;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>MSDFGEN_USE_CPP11;MSDFGEN_USE_SKIA;MSDFGEN_STANDALONE;MSDFGEN_USE_OPENMP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<OpenMPSupport>true</OpenMPSupport>
</ClCompile>
@ -407,7 +407,7 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<SubSystem>Console</SubSystem>
<AdditionalLibraryDirectories>freetype/win64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>freetype/win$(PlatformArchitecture);skia/win$(PlatformArchitecture)/release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>false</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
@ -418,8 +418,8 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>include;freetype/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>MSDFGEN_USE_CPP11;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>include;freetype/include;skia/include;skia/include/core;skia/include/config;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>MSDFGEN_USE_CPP11;MSDFGEN_USE_SKIA;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
@ -427,7 +427,7 @@
<OptimizeReferences>true</OptimizeReferences>
</Link>
<Lib>
<AdditionalLibraryDirectories>freetype/win64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>freetype/win$(PlatformArchitecture);skia/win$(PlatformArchitecture)/release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Library OpenMP|x64'">
@ -437,8 +437,8 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>include;freetype/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>MSDFGEN_USE_CPP11;MSDFGEN_USE_OPENMP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>include;freetype/include;skia/include;skia/include/core;skia/include/config;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>MSDFGEN_USE_CPP11;MSDFGEN_USE_SKIA;MSDFGEN_USE_OPENMP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<OpenMPSupport>true</OpenMPSupport>
</ClCompile>
@ -447,7 +447,7 @@
<OptimizeReferences>true</OptimizeReferences>
</Link>
<Lib>
<AdditionalLibraryDirectories>freetype/win64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>freetype/win$(PlatformArchitecture);skia/win$(PlatformArchitecture)/release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
@ -481,6 +481,7 @@
<ClInclude Include="core\Vector2.h" />
<ClInclude Include="ext\import-font.h" />
<ClInclude Include="ext\import-svg.h" />
<ClInclude Include="ext\resolve-shape-geometry.h" />
<ClInclude Include="ext\save-png.h" />
<ClInclude Include="msdfgen-ext.h" />
<ClInclude Include="msdfgen.h" />
@ -508,6 +509,7 @@
<ClCompile Include="core\Vector2.cpp" />
<ClCompile Include="ext\import-font.cpp" />
<ClCompile Include="ext\import-svg.cpp" />
<ClCompile Include="ext\resolve-shape-geometry.cpp" />
<ClCompile Include="ext\save-png.cpp" />
<ClCompile Include="lib\lodepng.cpp" />
<ClCompile Include="lib\tinyxml2.cpp" />

View File

@ -120,6 +120,9 @@
<ClInclude Include="core\msdf-edge-artifact-patcher.h">
<Filter>Core</Filter>
</ClInclude>
<ClInclude Include="ext\resolve-shape-geometry.h">
<Filter>Extensions</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
@ -200,6 +203,9 @@
<ClCompile Include="core\msdf-edge-artifact-patcher.cpp">
<Filter>Core</Filter>
</ClCompile>
<ClCompile Include="ext\resolve-shape-geometry.cpp">
<Filter>Extensions</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Msdfgen.rc">

View File

@ -26,7 +26,8 @@ Extensions contain utilities for loading fonts and SVG files, as well as saving
Those are exposed by the [msdfgen-ext.h](msdfgen-ext.h) header. This module uses
[FreeType](http://www.freetype.org/),
[TinyXML2](http://www.grinninglizard.com/tinyxml2/),
and [LodePNG](http://lodev.org/lodepng/).
[LodePNG](http://lodev.org/lodepng/),
and (optionally) [Skia](https://skia.org/).
Additionally, there is the [main.cpp](main.cpp), which wraps the functionality into
a comprehensive standalone console program. To start using the program immediately,

View File

@ -0,0 +1,89 @@
#include "resolve-shape-geometry.h"
#ifdef MSDFGEN_USE_SKIA
#include <core/SkPath.h>
#include <pathops/SkPathOps.h>
#include "../core/Vector2.h"
#include "../core/edge-segments.h"
#include "../core/Contour.h"
#ifdef _WIN32
#pragma comment(lib, "skia.lib")
#endif
namespace msdfgen {
SkPoint pointToSkiaPoint(Point2 p) {
return SkPoint::Make((SkScalar) p.x, (SkScalar) p.y);
}
Point2 pointFromSkiaPoint(const SkPoint p) {
return Point2((double) p.x(), (double) p.y());
}
void shapeToSkiaPath(SkPath &skPath, const Shape &shape) {
for (std::vector<Contour>::const_iterator contour = shape.contours.begin(); contour != shape.contours.end(); ++contour) {
if (!contour->edges.empty()) {
skPath.moveTo(pointToSkiaPoint(contour->edges.front()->point(0)));
for (std::vector<EdgeHolder>::const_iterator edge = contour->edges.begin(); edge != contour->edges.end(); ++edge) {
{
const LinearSegment *linearSegment = dynamic_cast<const LinearSegment *>(&**edge);
if (linearSegment)
skPath.lineTo(pointToSkiaPoint(linearSegment->p[1]));
} {
const QuadraticSegment *quadraticSegment = dynamic_cast<const QuadraticSegment *>(&**edge);
if (quadraticSegment)
skPath.quadTo(pointToSkiaPoint(quadraticSegment->p[1]), pointToSkiaPoint(quadraticSegment->p[2]));
} {
const CubicSegment *cubicSegment = dynamic_cast<const CubicSegment *>(&**edge);
if (cubicSegment)
skPath.cubicTo(pointToSkiaPoint(cubicSegment->p[1]), pointToSkiaPoint(cubicSegment->p[2]), pointToSkiaPoint(cubicSegment->p[3]));
}
}
}
}
}
void shapeFromSkiaPath(Shape &shape, const SkPath &skPath) {
shape.contours.clear();
Contour *contour = &shape.addContour();
SkPath::Iter pathIterator(skPath, true);
SkPoint edgePoints[4];
for (SkPath::Verb op; (op = pathIterator.next(edgePoints)) != SkPath::kDone_Verb;) {
switch (op) {
case SkPath::kMove_Verb:
if (!contour->edges.empty())
contour = &shape.addContour();
break;
case SkPath::kLine_Verb:
contour->addEdge(new LinearSegment(pointFromSkiaPoint(edgePoints[0]), pointFromSkiaPoint(edgePoints[1])));
break;
case SkPath::kQuad_Verb:
contour->addEdge(new QuadraticSegment(pointFromSkiaPoint(edgePoints[0]), pointFromSkiaPoint(edgePoints[1]), pointFromSkiaPoint(edgePoints[2])));
break;
case SkPath::kCubic_Verb:
contour->addEdge(new CubicSegment(pointFromSkiaPoint(edgePoints[0]), pointFromSkiaPoint(edgePoints[1]), pointFromSkiaPoint(edgePoints[2]), pointFromSkiaPoint(edgePoints[3])));
break;
default:;
}
}
if (contour->edges.empty())
shape.contours.pop_back();
}
bool resolveShapeGeometry(Shape &shape) {
SkPath skPath;
shapeToSkiaPath(skPath, shape);
if (!Simplify(skPath, &skPath))
return false;
// Skia's AsWinding doesn't seem to work for unknown reasons
shapeFromSkiaPath(shape, skPath);
shape.orientContours();
return true;
}
}
#endif

View File

@ -0,0 +1,15 @@
#pragma once
#include "../core/Shape.h"
#ifdef MSDFGEN_USE_SKIA
namespace msdfgen {
/// Resolves any intersections within the shape by subdividing its contours using the Skia library and makes sure its contours have a consistent winding.
bool resolveShapeGeometry(Shape &shape);
}
#endif

View File

@ -1,6 +1,6 @@
/*
* MULTI-CHANNEL SIGNED DISTANCE FIELD GENERATOR v1.7 (2020-03-07) - standalone console program
* MULTI-CHANNEL SIGNED DISTANCE FIELD GENERATOR v1.8 (2020-10-17) - standalone console program
* --------------------------------------------------------------------------------------------
* A utility by Viktor Chlumsky, (c) 2014 - 2020
*
@ -252,10 +252,24 @@ static const char * writeOutput(const BitmapConstRef<float, N> &bitmap, const ch
return NULL;
}
#if defined(MSDFGEN_USE_SKIA) && defined(MSDFGEN_USE_OPENMP)
#define TITLE_SUFFIX " with Skia & OpenMP"
#define EXTRA_UNDERLINE "-------------------"
#elif defined(MSDFGEN_USE_SKIA)
#define TITLE_SUFFIX " with Skia"
#define EXTRA_UNDERLINE "----------"
#elif defined(MSDFGEN_USE_OPENMP)
#define TITLE_SUFFIX " with OpenMP"
#define EXTRA_UNDERLINE "------------"
#else
#define TITLE_SUFFIX
#define EXTRA_UNDERLINE
#endif
static const char *helpText =
"\n"
"Multi-channel signed distance field generator by Viktor Chlumsky v" MSDFGEN_VERSION "\n"
"---------------------------------------------------------------------\n"
"Multi-channel signed distance field generator by Viktor Chlumsky v" MSDFGEN_VERSION TITLE_SUFFIX "\n"
"---------------------------------------------------------------------" EXTRA_UNDERLINE "\n"
" Usage: msdfgen"
#ifdef _WIN32
".exe"
@ -273,7 +287,8 @@ static const char *helpText =
" -defineshape <definition>\n"
"\tDefines input shape using the ad-hoc text definition.\n"
" -font <filename.ttf> <character code>\n"
"\tLoads a single glyph from the specified font file. Format of character code is '?', 63, 0x3F (Unicode value), or g34 (glyph index).\n"
"\tLoads a single glyph from the specified font file.\n"
"\tFormat of character code is '?', 63, 0x3F (Unicode value), or g34 (glyph index).\n"
" -shapedesc <filename.txt>\n"
"\tLoads text shape description from a file.\n"
" -stdin\n"
@ -281,6 +296,7 @@ static const char *helpText =
" -svg <filename.svg>\n"
"\tLoads the last vector path found in the specified SVG file.\n"
"\n"
// Keep alphabetical order!
"OPTIONS\n"
" -angle <angle>\n"
"\tSpecifies the minimum angle between adjacent edges to be considered a corner. Append D for degrees.\n"
@ -310,12 +326,21 @@ static const char *helpText =
"\tDisplays this help.\n"
" -legacy\n"
"\tUses the original (legacy) distance field algorithms.\n"
#ifdef MSDFGEN_USE_SKIA
" -nopreprocess\n"
"\tDisables path preprocessing which resolves self-intersections and overlapping contours.\n"
#else
" -nooverlap\n"
"\tDisables resolution of overlapping contours.\n"
" -noscanline\n"
"\tDisables the scanline pass, which corrects the distance field's signs according to the selected fill rule.\n"
#endif
" -o <filename>\n"
"\tSets the output file name. The default value is \"output.png\".\n"
#ifdef MSDFGEN_USE_SKIA
" -overlap\n"
"\tSwitches to distance field generator with support for overlapping contours.\n"
#endif
" -printmetrics\n"
"\tPrints relevant metrics of the shape to the standard output.\n"
" -pxrange <range>\n"
@ -323,9 +348,13 @@ static const char *helpText =
" -range <range>\n"
"\tSets the width of the range between the lowest and highest signed distance in shape units.\n"
" -reverseorder\n"
"\tGenerates the distance field as if shape vertices were in reverse order.\n"
"\tGenerates the distance field as if the shape's vertices were in reverse order.\n"
" -scale <scale>\n"
"\tSets the scale used to convert shape units to pixels.\n"
#ifdef MSDFGEN_USE_SKIA
" -scanline\n"
"\tPerforms an additional scanline pass to fix the signs of the distances.\n"
#endif
" -seed <n>\n"
"\tSets the random seed for edge coloring heuristic.\n"
" -size <width> <height>\n"
@ -362,8 +391,15 @@ int main(int argc, const char * const *argv) {
METRICS
} mode = MULTI;
bool legacyMode = false;
bool overlapSupport = true;
bool scanlinePass = true;
bool geometryPreproc = (
#ifdef MSDFGEN_USE_SKIA
true
#else
false
#endif
);
bool overlapSupport = !geometryPreproc;
bool scanlinePass = !geometryPreproc;
FillRule fillRule = FILL_NONZERO;
Format format = AUTO;
const char *input = NULL;
@ -477,11 +513,26 @@ int main(int argc, const char * const *argv) {
argPos += 1;
continue;
}
ARG_CASE("-nopreprocess", 0) {
geometryPreproc = false;
argPos += 1;
continue;
}
ARG_CASE("-preprocess", 0) {
geometryPreproc = true;
argPos += 1;
continue;
}
ARG_CASE("-nooverlap", 0) {
overlapSupport = false;
argPos += 1;
continue;
}
ARG_CASE("-overlap", 0) {
overlapSupport = true;
argPos += 1;
continue;
}
ARG_CASE("-noscanline", 0) {
scanlinePass = false;
argPos += 1;
@ -493,6 +544,7 @@ int main(int argc, const char * const *argv) {
continue;
}
ARG_CASE("-fillrule", 1) {
scanlinePass = true;
if (!strcmp(argv[argPos+1], "nonzero")) fillRule = FILL_NONZERO;
else if (!strcmp(argv[argPos+1], "evenodd") || !strcmp(argv[argPos+1], "odd")) fillRule = FILL_ODD;
else if (!strcmp(argv[argPos+1], "positive")) fillRule = FILL_POSITIVE;
@ -749,6 +801,14 @@ int main(int argc, const char * const *argv) {
// Validate and normalize shape
if (!shape.validate())
ABORT("The geometry of the loaded shape is invalid.");
if (geometryPreproc) {
#ifdef MSDFGEN_USE_SKIA
if (!resolveShapeGeometry(shape))
puts("Shape geometry preprocessing failed, skipping.");
#else
ABORT("Shape geometry preprocessing (-preprocess) is not available in this version because the Skia library is not present.");
#endif
}
shape.normalize();
if (yFlip)
shape.inverseYAxis = !shape.inverseYAxis;

View File

@ -2,13 +2,15 @@
#pragma once
/*
* MULTI-CHANNEL SIGNED DISTANCE FIELD GENERATOR v1.7 (2020-03-07) - extensions
* MULTI-CHANNEL SIGNED DISTANCE FIELD GENERATOR v1.8 (2020-10-17) - extensions
* ----------------------------------------------------------------------------
* A utility by Viktor Chlumsky, (c) 2014 - 2020
*
* The extension module provides ways to easily load input and save output using popular formats.
*
* Third party dependencies in extension module:
* - Skia by Google
* (to resolve self-intersecting paths)
* - FreeType 2
* (to load input font files)
* - TinyXML 2 by Lee Thomason
@ -18,6 +20,7 @@
*
*/
#include "ext/resolve-shape-geometry.h"
#include "ext/save-png.h"
#include "ext/import-svg.h"
#include "ext/import-font.h"

View File

@ -2,7 +2,7 @@
#pragma once
/*
* MULTI-CHANNEL SIGNED DISTANCE FIELD GENERATOR v1.7 (2020-03-07)
* MULTI-CHANNEL SIGNED DISTANCE FIELD GENERATOR v1.8 (2020-10-17)
* ---------------------------------------------------------------
* A utility by Viktor Chlumsky, (c) 2014 - 2020
*
@ -32,7 +32,7 @@
#include "core/save-tiff.h"
#include "core/shape-description.h"
#define MSDFGEN_VERSION "1.7"
#define MSDFGEN_VERSION "1.8"
namespace msdfgen {

29
skia/LICENSE vendored Normal file
View File

@ -0,0 +1,29 @@
// Copyright (c) 2011 Google Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------

View File

@ -0,0 +1,40 @@
/*
* Copyright 2017 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkAndroidFrameworkUtils_DEFINED
#define SkAndroidFrameworkUtils_DEFINED
#include "SkTypes.h"
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
class SkCanvas;
/**
* SkAndroidFrameworkUtils expose private APIs used only by Android framework.
*/
class SkAndroidFrameworkUtils {
public:
#if SK_SUPPORT_GPU
/**
* clipWithStencil draws the current clip into a stencil buffer with reference value and mask
* set to 0x1. This function works only on a GPU canvas.
*
* @param canvas A GPU canvas that has a non-empty clip.
*
* @return true on success or false if clip is empty or not a GPU canvas.
*/
static bool clipWithStencil(SkCanvas* canvas);
#endif //SK_SUPPORT_GPU
static void SafetyNetLog(const char*);
};
#endif // SK_BUILD_FOR_ANDROID_ANDROID
#endif // SkAndroidFrameworkUtils_DEFINED

154
skia/include/android/SkAnimatedImage.h vendored Normal file
View File

@ -0,0 +1,154 @@
/*
* Copyright 2018 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkAnimatedImage_DEFINED
#define SkAnimatedImage_DEFINED
#include "SkBitmap.h"
#include "SkCodecAnimation.h"
#include "SkDrawable.h"
#include "SkMatrix.h"
#include "SkRect.h"
class SkAndroidCodec;
class SkPicture;
/**
* Thread unsafe drawable for drawing animated images (e.g. GIF).
*/
class SK_API SkAnimatedImage : public SkDrawable {
public:
/**
* Create an SkAnimatedImage from the SkAndroidCodec.
*
* Returns null on failure to allocate pixels. On success, this will
* decode the first frame.
*
* @param scaledSize Size to draw the image, possibly requiring scaling.
* @param cropRect Rectangle to crop to after scaling.
* @param postProcess Picture to apply after scaling and cropping.
*/
static sk_sp<SkAnimatedImage> Make(std::unique_ptr<SkAndroidCodec>,
SkISize scaledSize, SkIRect cropRect, sk_sp<SkPicture> postProcess);
/**
* Simpler version that uses the default size, no cropping, and no postProcess.
*/
static sk_sp<SkAnimatedImage> Make(std::unique_ptr<SkAndroidCodec>);
~SkAnimatedImage() override;
/**
* Reset the animation to the beginning.
*/
void reset();
/**
* Whether the animation completed.
*
* Returns true after all repetitions are complete, or an error stops the
* animation. Gets reset to false if the animation is restarted.
*/
bool isFinished() const { return fFinished; }
/**
* Returned by decodeNextFrame and currentFrameDuration if the animation
* is not running.
*/
static constexpr int kFinished = -1;
/**
* Decode the next frame.
*
* If the animation is on the last frame or has hit an error, returns
* kFinished.
*/
int decodeNextFrame();
/**
* How long to display the current frame.
*
* Useful for the first frame, for which decodeNextFrame is called
* internally.
*/
int currentFrameDuration() {
return fCurrentFrameDuration;
}
/**
* Change the repetition count.
*
* By default, the image will repeat the number of times indicated in the
* encoded data.
*
* Use SkCodec::kRepetitionCountInfinite for infinite, and 0 to show all
* frames once and then stop.
*/
void setRepetitionCount(int count);
/**
* Return the currently set repetition count.
*/
int getRepetitionCount() const {
return fRepetitionCount;
}
protected:
SkRect onGetBounds() override;
void onDraw(SkCanvas*) override;
private:
struct Frame {
SkBitmap fBitmap;
int fIndex;
SkCodecAnimation::DisposalMethod fDisposalMethod;
// init() may have to create a new SkPixelRef, if the
// current one is already in use by another owner (e.g.
// an SkPicture). This determines whether to copy the
// existing one to the new one.
enum class OnInit {
// Restore the image from the old SkPixelRef to the
// new one.
kRestoreIfNecessary,
// No need to restore.
kNoRestore,
};
Frame();
bool init(const SkImageInfo& info, OnInit);
bool copyTo(Frame*) const;
};
std::unique_ptr<SkAndroidCodec> fCodec;
const SkISize fScaledSize;
const SkImageInfo fDecodeInfo;
const SkIRect fCropRect;
const sk_sp<SkPicture> fPostProcess;
const int fFrameCount;
const bool fSimple; // no crop, scale, or postprocess
SkMatrix fMatrix; // used only if !fSimple
bool fFinished;
int fCurrentFrameDuration;
Frame fDisplayFrame;
Frame fDecodingFrame;
Frame fRestoreFrame;
int fRepetitionCount;
int fRepetitionsCompleted;
SkAnimatedImage(std::unique_ptr<SkAndroidCodec>, SkISize scaledSize,
SkImageInfo decodeInfo, SkIRect cropRect, sk_sp<SkPicture> postProcess);
SkAnimatedImage(std::unique_ptr<SkAndroidCodec>);
int computeNextFrame(int current, bool* animationEnded);
double finish();
typedef SkDrawable INHERITED;
};
#endif // SkAnimatedImage_DEFINED

29
skia/include/android/SkBRDAllocator.h vendored Normal file
View File

@ -0,0 +1,29 @@
/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkBRDAllocator_DEFINED
#define SkBRDAllocator_DEFINED
#include "SkBitmap.h"
#include "SkCodec.h"
/**
* Abstract subclass of SkBitmap's allocator.
* Allows the allocator to indicate if the memory it allocates
* is zero initialized.
*/
class SkBRDAllocator : public SkBitmap::Allocator {
public:
/**
* Indicates if the memory allocated by this allocator is
* zero initialized.
*/
virtual SkCodec::ZeroInitialized zeroInit() const = 0;
};
#endif // SkBRDAllocator_DEFINED

View File

@ -0,0 +1,92 @@
/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkBitmapRegionDecoder_DEFINED
#define SkBitmapRegionDecoder_DEFINED
#include "SkBitmap.h"
#include "SkBRDAllocator.h"
#include "SkEncodedImageFormat.h"
#include "SkStream.h"
/*
* This class aims to provide an interface to test multiple implementations of
* SkBitmapRegionDecoder.
*/
class SK_API SkBitmapRegionDecoder {
public:
enum Strategy {
kAndroidCodec_Strategy, // Uses SkAndroidCodec for scaling and subsetting
};
/*
* @param data Refs the data while this object exists, unrefs on destruction
* @param strategy Strategy used for scaling and subsetting
* @return Tries to create an SkBitmapRegionDecoder, returns NULL on failure
*/
static SkBitmapRegionDecoder* Create(sk_sp<SkData>, Strategy strategy);
/*
* @param stream Takes ownership of the stream
* @param strategy Strategy used for scaling and subsetting
* @return Tries to create an SkBitmapRegionDecoder, returns NULL on failure
*/
static SkBitmapRegionDecoder* Create(
SkStreamRewindable* stream, Strategy strategy);
/*
* Decode a scaled region of the encoded image stream
*
* @param bitmap Container for decoded pixels. It is assumed that the pixels
* are initially unallocated and will be allocated by this function.
* @param allocator Allocator for the pixels. If this is NULL, the default
* allocator (HeapAllocator) will be used.
* @param desiredSubset Subset of the original image to decode.
* @param sampleSize An integer downscaling factor for the decode.
* @param colorType Preferred output colorType.
* New implementations should return NULL if they do not support
* decoding to this color type.
* The old kOriginal_Strategy will decode to a default color type
* if this color type is unsupported.
* @param requireUnpremul If the image is not opaque, we will use this to determine the
* alpha type to use.
* @param prefColorSpace If non-null and supported, this is the color space that we will
* decode into. Otherwise, we will choose a default.
*
*/
virtual bool decodeRegion(SkBitmap* bitmap, SkBRDAllocator* allocator,
const SkIRect& desiredSubset, int sampleSize,
SkColorType colorType, bool requireUnpremul,
sk_sp<SkColorSpace> prefColorSpace = nullptr) = 0;
virtual SkEncodedImageFormat getEncodedFormat() = 0;
virtual SkColorType computeOutputColorType(SkColorType requestedColorType) = 0;
virtual sk_sp<SkColorSpace> computeOutputColorSpace(SkColorType outputColorType,
sk_sp<SkColorSpace> prefColorSpace = nullptr) = 0;
int width() const { return fWidth; }
int height() const { return fHeight; }
virtual ~SkBitmapRegionDecoder() {}
protected:
SkBitmapRegionDecoder(int width, int height)
: fWidth(width)
, fHeight(height)
{}
private:
const int fWidth;
const int fHeight;
};
#endif

View File

@ -0,0 +1,42 @@
/*
* Copyright 2017 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkAtlasTextContext_DEFINED
#define SkAtlasTextContext_DEFINED
#include "SkRefCnt.h"
class SkAtlasTextRenderer;
class SkInternalAtlasTextContext;
SkAtlasTextRenderer* SkGetAtlasTextRendererFromInternalContext(class SkInternalAtlasTextContext&);
/**
* Class that Atlas Text client uses to register their SkAtlasTextRenderer implementation and
* to create one or more SkAtlasTextTargets (destination surfaces for text rendering).
*/
class SK_API SkAtlasTextContext : public SkRefCnt {
public:
static sk_sp<SkAtlasTextContext> Make(sk_sp<SkAtlasTextRenderer>);
SkAtlasTextRenderer* renderer() const {
return SkGetAtlasTextRendererFromInternalContext(*fInternalContext);
}
SkInternalAtlasTextContext& internal() { return *fInternalContext; }
private:
SkAtlasTextContext() = delete;
SkAtlasTextContext(const SkAtlasTextContext&) = delete;
SkAtlasTextContext& operator=(const SkAtlasTextContext&) = delete;
SkAtlasTextContext(sk_sp<SkAtlasTextRenderer>);
std::unique_ptr<SkInternalAtlasTextContext> fInternalContext;
};
#endif

View File

@ -0,0 +1,35 @@
/*
* Copyright 2017 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkAtlasTextFont_DEFINED
#define SkAtlasTextFont_DEFINED
#include "SkRefCnt.h"
#include "SkTypeface.h"
/** Represents a font at a size. TODO: What else do we need here (skewX, scaleX, vertical, ...)? */
class SK_API SkAtlasTextFont : public SkRefCnt {
public:
static sk_sp<SkAtlasTextFont> Make(sk_sp<SkTypeface> typeface, SkScalar size) {
return sk_sp<SkAtlasTextFont>(new SkAtlasTextFont(std::move(typeface), size));
}
SkTypeface* typeface() const { return fTypeface.get(); }
sk_sp<SkTypeface> refTypeface() const { return fTypeface; }
SkScalar size() const { return fSize; }
private:
SkAtlasTextFont(sk_sp<SkTypeface> typeface, SkScalar size)
: fTypeface(std::move(typeface)), fSize(size) {}
sk_sp<SkTypeface> fTypeface;
SkScalar fSize;
};
#endif

View File

@ -0,0 +1,72 @@
/*
* Copyright 2017 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "SkPoint3.h"
#include "SkRefCnt.h"
#ifndef SkAtlasTextRenderer_DEFINED
#define SkAtlasTextRenderer_DEFINED
/**
* This is the base class for a renderer implemented by the SkAtlasText client. The
* SkAtlasTextContext issues texture creations, deletions, uploads, and vertex draws to the
* renderer. The renderer must perform those actions in the order called to correctly render
* the text drawn to SkAtlasTextTargets.
*/
class SK_API SkAtlasTextRenderer : public SkRefCnt {
public:
enum class AtlasFormat {
/** Unsigned normalized 8 bit single channel format. */
kA8
};
struct SDFVertex {
/** Position in device space (not normalized). The third component is w (not z). */
SkPoint3 fPosition;
/** Color, same value for all four corners of a glyph quad. */
uint32_t fColor;
/** Texture coordinate (in texel units, not normalized). */
int16_t fTextureCoordX;
int16_t fTextureCoordY;
};
virtual ~SkAtlasTextRenderer() = default;
/**
* Create a texture of the provided format with dimensions 'width' x 'height'
* and return a unique handle.
*/
virtual void* createTexture(AtlasFormat, int width, int height) = 0;
/**
* Delete the texture with the passed handle.
*/
virtual void deleteTexture(void* textureHandle) = 0;
/**
* Place the pixel data specified by 'data' in the texture with handle
* 'textureHandle' in the rectangle ['x', 'x' + 'width') x ['y', 'y' + 'height').
* 'rowBytes' specifies the byte offset between successive rows in 'data' and will always be
* a multiple of the number of bytes per pixel.
* The pixel format of data is the same as that of 'textureHandle'.
*/
virtual void setTextureData(void* textureHandle, const void* data, int x, int y, int width,
int height, size_t rowBytes) = 0;
/**
* Draws glyphs using SDFs. The SDF data resides in 'textureHandle'. The array
* 'vertices' provides interleaved device-space positions, colors, and
* texture coordinates. There are are 4 * 'quadCnt' entries in 'vertices'.
*/
virtual void drawSDFGlyphs(void* targetHandle, void* textureHandle, const SDFVertex vertices[],
int quadCnt) = 0;
/** Called when a SkAtlasTextureTarget is destroyed. */
virtual void targetDeleted(void* targetHandle) = 0;
};
#endif

View File

@ -0,0 +1,100 @@
/*
* Copyright 2017 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkAtlasTextTarget_DEFINED
#define SkAtlasTextTarget_DEFINED
#include "SkDeque.h"
#include "SkRefCnt.h"
#include "SkScalar.h"
#include <memory>
class SkAtlasTextContext;
class SkAtlasTextFont;
class SkMatrix;
struct SkPoint;
/** Represents a client-created renderable surface and is used to draw text into the surface. */
class SK_API SkAtlasTextTarget {
public:
virtual ~SkAtlasTextTarget();
/**
* Creates a text drawing target. handle is used to identify this rendering surface when
* draws are flushed to the SkAtlasTextContext's SkAtlasTextRenderer.
*/
static std::unique_ptr<SkAtlasTextTarget> Make(sk_sp<SkAtlasTextContext>,
int width,
int height,
void* handle);
/**
* Enqueues a text draw in the target. The caller provides an array of glyphs and their
* positions. The meaning of 'color' here is interpreted by the client's SkAtlasTextRenderer
* when it actually renders the text.
*/
virtual void drawText(const SkGlyphID[], const SkPoint[], int glyphCnt, uint32_t color,
const SkAtlasTextFont&) = 0;
/** Issues all queued text draws to SkAtlasTextRenderer. */
virtual void flush() = 0;
int width() const { return fWidth; }
int height() const { return fHeight; }
void* handle() const { return fHandle; }
SkAtlasTextContext* context() const { return fContext.get(); }
/** Saves the current matrix in a stack. Returns the prior depth of the saved matrix stack. */
int save();
/** Pops the top matrix on the stack if the stack is not empty. */
void restore();
/**
* Pops the matrix stack until the stack depth is count. Does nothing if the depth is already
* less than count.
*/
void restoreToCount(int count);
/** Pre-translates the current CTM. */
void translate(SkScalar dx, SkScalar dy);
/** Pre-scales the current CTM. */
void scale(SkScalar sx, SkScalar sy);
/** Pre-rotates the current CTM about the origin. */
void rotate(SkScalar degrees);
/** Pre-rotates the current CTM about the (px, py). */
void rotate(SkScalar degrees, SkScalar px, SkScalar py);
/** Pre-skews the current CTM. */
void skew(SkScalar sx, SkScalar sy);
/** Pre-concats the current CTM. */
void concat(const SkMatrix& matrix);
protected:
SkAtlasTextTarget(sk_sp<SkAtlasTextContext>, int width, int height, void* handle);
const SkMatrix& ctm() const { return *static_cast<const SkMatrix*>(fMatrixStack.back()); }
void* const fHandle;
const sk_sp<SkAtlasTextContext> fContext;
const int fWidth;
const int fHeight;
private:
SkDeque fMatrixStack;
int fSaveCnt;
SkMatrix* accessCTM() const {
return static_cast<SkMatrix*>(const_cast<void*>(fMatrixStack.back()));
}
SkAtlasTextTarget() = delete;
SkAtlasTextTarget(const SkAtlasTextContext&) = delete;
SkAtlasTextTarget& operator=(const SkAtlasTextContext&) = delete;
};
#endif

159
skia/include/c/sk_canvas.h vendored Normal file
View File

@ -0,0 +1,159 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL
// DO NOT USE -- FOR INTERNAL TESTING ONLY
#ifndef sk_canvas_DEFINED
#define sk_canvas_DEFINED
#include "sk_types.h"
SK_C_PLUS_PLUS_BEGIN_GUARD
/**
Save the current matrix and clip on the canvas. When the
balancing call to sk_canvas_restore() is made, the previous matrix
and clip are restored.
*/
SK_API void sk_canvas_save(sk_canvas_t*);
/**
This behaves the same as sk_canvas_save(), but in addition it
allocates an offscreen surface. All drawing calls are directed
there, and only when the balancing call to sk_canvas_restore() is
made is that offscreen transfered to the canvas (or the previous
layer).
@param sk_rect_t* (may be null) This rect, if non-null, is used as
a hint to limit the size of the offscreen, and
thus drawing may be clipped to it, though that
clipping is not guaranteed to happen. If exact
clipping is desired, use sk_canvas_clip_rect().
@param sk_paint_t* (may be null) The paint is copied, and is applied
to the offscreen when sk_canvas_restore() is
called.
*/
SK_API void sk_canvas_save_layer(sk_canvas_t*, const sk_rect_t*, const sk_paint_t*);
/**
This call balances a previous call to sk_canvas_save() or
sk_canvas_save_layer(), and is used to remove all modifications to
the matrix and clip state since the last save call. It is an
error to call sk_canvas_restore() more times than save and
save_layer were called.
*/
SK_API void sk_canvas_restore(sk_canvas_t*);
/**
Preconcat the current coordinate transformation matrix with the
specified translation.
*/
SK_API void sk_canvas_translate(sk_canvas_t*, float dx, float dy);
/**
Preconcat the current coordinate transformation matrix with the
specified scale.
*/
SK_API void sk_canvas_scale(sk_canvas_t*, float sx, float sy);
/**
Preconcat the current coordinate transformation matrix with the
specified rotation in degrees.
*/
SK_API void sk_canvas_rotate_degrees(sk_canvas_t*, float degrees);
/**
Preconcat the current coordinate transformation matrix with the
specified rotation in radians.
*/
SK_API void sk_canvas_rotate_radians(sk_canvas_t*, float radians);
/**
Preconcat the current coordinate transformation matrix with the
specified skew.
*/
SK_API void sk_canvas_skew(sk_canvas_t*, float sx, float sy);
/**
Preconcat the current coordinate transformation matrix with the
specified matrix.
*/
SK_API void sk_canvas_concat(sk_canvas_t*, const sk_matrix_t*);
/**
Modify the current clip with the specified rectangle. The new
current clip will be the intersection of the old clip and the
rectange.
*/
SK_API void sk_canvas_clip_rect(sk_canvas_t*, const sk_rect_t*);
/**
Modify the current clip with the specified path. The new
current clip will be the intersection of the old clip and the
path.
*/
SK_API void sk_canvas_clip_path(sk_canvas_t*, const sk_path_t*);
/**
Fill the entire canvas (restricted to the current clip) with the
specified paint.
*/
SK_API void sk_canvas_draw_paint(sk_canvas_t*, const sk_paint_t*);
/**
Draw the specified rectangle using the specified paint. The
rectangle will be filled or stroked based on the style in the
paint.
*/
SK_API void sk_canvas_draw_rect(sk_canvas_t*, const sk_rect_t*, const sk_paint_t*);
/**
* Draw the circle centered at (cx, cy) with radius rad using the specified paint.
* The circle will be filled or framed based on the style in the paint
*/
SK_API void sk_canvas_draw_circle(sk_canvas_t*, float cx, float cy, float rad, const sk_paint_t*);
/**
Draw the specified oval using the specified paint. The oval will be
filled or framed based on the style in the paint
*/
SK_API void sk_canvas_draw_oval(sk_canvas_t*, const sk_rect_t*, const sk_paint_t*);
/**
Draw the specified path using the specified paint. The path will be
filled or framed based on the style in the paint
*/
SK_API void sk_canvas_draw_path(sk_canvas_t*, const sk_path_t*, const sk_paint_t*);
/**
Draw the specified image, with its top/left corner at (x,y), using
the specified paint, transformed by the current matrix.
@param sk_paint_t* (may be NULL) the paint used to draw the image.
*/
SK_API void sk_canvas_draw_image(sk_canvas_t*, const sk_image_t*,
float x, float y, const sk_paint_t*);
/**
Draw the specified image, scaling and translating so that it fills
the specified dst rect. If the src rect is non-null, only that
subset of the image is transformed and drawn.
@param sk_paint_t* (may be NULL) The paint used to draw the image.
*/
SK_API void sk_canvas_draw_image_rect(sk_canvas_t*, const sk_image_t*,
const sk_rect_t* src,
const sk_rect_t* dst, const sk_paint_t*);
/**
Draw the picture into this canvas (replay the pciture's drawing commands).
@param sk_matrix_t* If non-null, apply that matrix to the CTM when
drawing this picture. This is logically
equivalent to: save, concat, draw_picture,
restore.
@param sk_paint_t* If non-null, draw the picture into a temporary
buffer, and then apply the paint's alpha,
colorfilter, imagefilter, and xfermode to that
buffer as it is drawn to the canvas. This is
logically equivalent to save_layer(paint),
draw_picture, restore.
*/
SK_API void sk_canvas_draw_picture(sk_canvas_t*, const sk_picture_t*,
const sk_matrix_t*, const sk_paint_t*);
SK_C_PLUS_PLUS_END_GUARD
#endif

25
skia/include/c/sk_colorspace.h vendored Normal file
View File

@ -0,0 +1,25 @@
/*
* Copyright 2018 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL
// DO NOT USE -- FOR INTERNAL TESTING ONLY
#ifndef sk_imageinfo_DEFINED
#define sk_imageinfo_DEFINED
#include "sk_types.h"
SK_C_PLUS_PLUS_BEGIN_GUARD
sk_colorspace_t* sk_colorspace_new_srgb();
void sk_colorspace_ref(sk_colorspace_t*);
void sk_colorspace_unref(sk_colorspace_t*);
SK_C_PLUS_PLUS_END_GUARD
#endif

70
skia/include/c/sk_data.h vendored Normal file
View File

@ -0,0 +1,70 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL
// DO NOT USE -- FOR INTERNAL TESTING ONLY
#ifndef sk_data_DEFINED
#define sk_data_DEFINED
#include "sk_types.h"
SK_C_PLUS_PLUS_BEGIN_GUARD
/**
Returns a new empty sk_data_t. This call must be balanced with a call to
sk_data_unref().
*/
SK_API sk_data_t* sk_data_new_empty(void);
/**
Returns a new sk_data_t by copying the specified source data.
This call must be balanced with a call to sk_data_unref().
*/
SK_API sk_data_t* sk_data_new_with_copy(const void* src, size_t length);
/**
Pass ownership of the given memory to a new sk_data_t, which will
call free() when the refernce count of the data goes to zero. For
example:
size_t length = 1024;
void* buffer = malloc(length);
memset(buffer, 'X', length);
sk_data_t* data = sk_data_new_from_malloc(buffer, length);
This call must be balanced with a call to sk_data_unref().
*/
SK_API sk_data_t* sk_data_new_from_malloc(const void* memory, size_t length);
/**
Returns a new sk_data_t using a subset of the data in the
specified source sk_data_t. This call must be balanced with a
call to sk_data_unref().
*/
SK_API sk_data_t* sk_data_new_subset(const sk_data_t* src, size_t offset, size_t length);
/**
Increment the reference count on the given sk_data_t. Must be
balanced by a call to sk_data_unref().
*/
SK_API void sk_data_ref(const sk_data_t*);
/**
Decrement the reference count. If the reference count is 1 before
the decrement, then release both the memory holding the sk_data_t
and the memory it is managing. New sk_data_t are created with a
reference count of 1.
*/
SK_API void sk_data_unref(const sk_data_t*);
/**
Returns the number of bytes stored.
*/
SK_API size_t sk_data_get_size(const sk_data_t*);
/**
Returns the pointer to the data.
*/
SK_API const void* sk_data_get_data(const sk_data_t*);
SK_C_PLUS_PLUS_END_GUARD
#endif

71
skia/include/c/sk_image.h vendored Normal file
View File

@ -0,0 +1,71 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL
// DO NOT USE -- FOR INTERNAL TESTING ONLY
#ifndef sk_image_DEFINED
#define sk_image_DEFINED
#include "sk_types.h"
SK_C_PLUS_PLUS_BEGIN_GUARD
/**
* Return a new image that has made a copy of the provided pixels, or NULL on failure.
* Balance with a call to sk_image_unref().
*/
SK_API sk_image_t* sk_image_new_raster_copy(const sk_imageinfo_t*, const void* pixels, size_t rowBytes);
/**
* If the specified data can be interpreted as a compressed image (e.g. PNG or JPEG) then this
* returns an image. If the encoded data is not supported, returns NULL.
*
* On success, the encoded data may be processed immediately, or it may be ref()'d for later
* use.
*/
SK_API sk_image_t* sk_image_new_from_encoded(const sk_data_t* encoded, const sk_irect_t* subset);
/**
* Encode the image's pixels and return the result as a new PNG in a
* sk_data_t, which the caller must manage: call sk_data_unref() when
* they are done.
*
* If the image type cannot be encoded, this will return NULL.
*/
SK_API sk_data_t* sk_image_encode(const sk_image_t*);
/**
* Increment the reference count on the given sk_image_t. Must be
* balanced by a call to sk_image_unref().
*/
SK_API void sk_image_ref(const sk_image_t*);
/**
* Decrement the reference count. If the reference count is 1 before
* the decrement, then release both the memory holding the sk_image_t
* and the memory it is managing. New sk_image_t are created with a
reference count of 1.
*/
SK_API void sk_image_unref(const sk_image_t*);
/**
* Return the width of the sk_image_t/
*/
SK_API int sk_image_get_width(const sk_image_t*);
/**
* Return the height of the sk_image_t/
*/
SK_API int sk_image_get_height(const sk_image_t*);
/**
* Returns a non-zero value unique among all images.
*/
SK_API uint32_t sk_image_get_unique_id(const sk_image_t*);
SK_C_PLUS_PLUS_END_GUARD
#endif

62
skia/include/c/sk_imageinfo.h vendored Normal file
View File

@ -0,0 +1,62 @@
/*
* Copyright 2018 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL
// DO NOT USE -- FOR INTERNAL TESTING ONLY
#ifndef sk_imageinfo_DEFINED
#define sk_imageinfo_DEFINED
#include "sk_types.h"
SK_C_PLUS_PLUS_BEGIN_GUARD
typedef enum {
UNKNOWN_SK_COLORTYPE,
RGBA_8888_SK_COLORTYPE,
BGRA_8888_SK_COLORTYPE,
ALPHA_8_SK_COLORTYPE,
GRAY_8_SK_COLORTYPE,
RGBA_F16_SK_COLORTYPE,
RGBA_F32_SK_COLORTYPE,
} sk_colortype_t;
typedef enum {
OPAQUE_SK_ALPHATYPE,
PREMUL_SK_ALPHATYPE,
UNPREMUL_SK_ALPHATYPE,
} sk_alphatype_t;
/**
* Allocate a new imageinfo object. If colorspace is not null, it's owner-count will be
* incremented automatically.
*/
sk_imageinfo_t* sk_imageinfo_new(int width, int height, sk_colortype_t ct, sk_alphatype_t at,
sk_colorspace_t* cs);
/**
* Free the imageinfo object. If it contains a reference to a colorspace, its owner-count will
* be decremented automatically.
*/
void sk_imageinfo_delete(sk_imageinfo_t*);
int32_t sk_imageinfo_get_width(sk_imageinfo_t*);
int32_t sk_imageinfo_get_height(sk_imageinfo_t*);
sk_colortype_t sk_imageinfo_get_colortype(sk_imageinfo_t*);
sk_alphatype_t sk_imageinfo_get_alphatype(sk_imageinfo_t*);
/**
* Return the colorspace object reference contained in the imageinfo, or null if there is none.
* Note: this does not modify the owner-count on the colorspace object. If the caller needs to
* use the colorspace beyond the lifetime of the imageinfo, it should manually call
* sk_colorspace_ref() (and then call unref() when it is done).
*/
sk_colorspace_t* sk_imageinfo_get_colorspace(sk_imageinfo_t*);
SK_C_PLUS_PLUS_END_GUARD
#endif

47
skia/include/c/sk_maskfilter.h vendored Normal file
View File

@ -0,0 +1,47 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL
// DO NOT USE -- FOR INTERNAL TESTING ONLY
#ifndef sk_maskfilter_DEFINED
#define sk_maskfilter_DEFINED
#include "sk_types.h"
typedef enum {
NORMAL_SK_BLUR_STYLE, //!< fuzzy inside and outside
SOLID_SK_BLUR_STYLE, //!< solid inside, fuzzy outside
OUTER_SK_BLUR_STYLE, //!< nothing inside, fuzzy outside
INNER_SK_BLUR_STYLE, //!< fuzzy inside, nothing outside
} sk_blurstyle_t;
SK_C_PLUS_PLUS_BEGIN_GUARD
/**
Increment the reference count on the given sk_maskfilter_t. Must be
balanced by a call to sk_maskfilter_unref().
*/
void sk_maskfilter_ref(sk_maskfilter_t*);
/**
Decrement the reference count. If the reference count is 1 before
the decrement, then release both the memory holding the
sk_maskfilter_t and any other associated resources. New
sk_maskfilter_t are created with a reference count of 1.
*/
void sk_maskfilter_unref(sk_maskfilter_t*);
/**
Create a blur maskfilter.
@param sk_blurstyle_t The SkBlurStyle to use
@param sigma Standard deviation of the Gaussian blur to apply. Must be > 0.
*/
sk_maskfilter_t* sk_maskfilter_new_blur(sk_blurstyle_t, float sigma);
SK_C_PLUS_PLUS_END_GUARD
#endif

49
skia/include/c/sk_matrix.h vendored Normal file
View File

@ -0,0 +1,49 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL
// DO NOT USE -- FOR INTERNAL TESTING ONLY
#ifndef sk_matrix_DEFINED
#define sk_matrix_DEFINED
#include "sk_types.h"
SK_C_PLUS_PLUS_BEGIN_GUARD
/** Set the matrix to identity */
void sk_matrix_set_identity(sk_matrix_t*);
/** Set the matrix to translate by (tx, ty). */
void sk_matrix_set_translate(sk_matrix_t*, float tx, float ty);
/**
Preconcats the matrix with the specified translation.
M' = M * T(dx, dy)
*/
void sk_matrix_pre_translate(sk_matrix_t*, float tx, float ty);
/**
Postconcats the matrix with the specified translation.
M' = T(dx, dy) * M
*/
void sk_matrix_post_translate(sk_matrix_t*, float tx, float ty);
/** Set the matrix to scale by sx and sy. */
void sk_matrix_set_scale(sk_matrix_t*, float sx, float sy);
/**
Preconcats the matrix with the specified scale.
M' = M * S(sx, sy)
*/
void sk_matrix_pre_scale(sk_matrix_t*, float sx, float sy);
/**
Postconcats the matrix with the specified scale.
M' = S(sx, sy) * M
*/
void sk_matrix_post_scale(sk_matrix_t*, float sx, float sy);
SK_C_PLUS_PLUS_END_GUARD
#endif

145
skia/include/c/sk_paint.h vendored Normal file
View File

@ -0,0 +1,145 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL
// DO NOT USE -- FOR INTERNAL TESTING ONLY
#ifndef sk_paint_DEFINED
#define sk_paint_DEFINED
#include "sk_types.h"
SK_C_PLUS_PLUS_BEGIN_GUARD
/**
Create a new paint with default settings:
antialias : false
stroke : false
stroke width : 0.0f (hairline)
stroke miter : 4.0f
stroke cap : BUTT_SK_STROKE_CAP
stroke join : MITER_SK_STROKE_JOIN
color : opaque black
shader : NULL
maskfilter : NULL
xfermode_mode : SRCOVER_SK_XFERMODE_MODE
*/
SK_API sk_paint_t* sk_paint_new(void);
/**
Release the memory storing the sk_paint_t and unref() all
associated objects.
*/
SK_API void sk_paint_delete(sk_paint_t*);
/**
Return true iff the paint has antialiasing enabled.
*/
SK_API bool sk_paint_is_antialias(const sk_paint_t*);
/**
Set to true to enable antialiasing, false to disable it on this
sk_paint_t.
*/
SK_API void sk_paint_set_antialias(sk_paint_t*, bool);
/**
Return the paint's curent drawing color.
*/
SK_API sk_color_t sk_paint_get_color(const sk_paint_t*);
/**
Set the paint's curent drawing color.
*/
SK_API void sk_paint_set_color(sk_paint_t*, sk_color_t);
/* stroke settings */
/**
Return true iff stroking is enabled rather than filling on this
sk_paint_t.
*/
SK_API bool sk_paint_is_stroke(const sk_paint_t*);
/**
Set to true to enable stroking rather than filling with this
sk_paint_t.
*/
SK_API void sk_paint_set_stroke(sk_paint_t*, bool);
/**
Return the width for stroking. A value of 0 strokes in hairline mode.
*/
SK_API float sk_paint_get_stroke_width(const sk_paint_t*);
/**
Set the width for stroking. A value of 0 strokes in hairline mode
(always draw 1-pixel wide, regardless of the matrix).
*/
SK_API void sk_paint_set_stroke_width(sk_paint_t*, float width);
/**
Return the paint's stroke miter value. This is used to control the
behavior of miter joins when the joins angle is sharp.
*/
SK_API float sk_paint_get_stroke_miter(const sk_paint_t*);
/**
Set the paint's stroke miter value. This is used to control the
behavior of miter joins when the joins angle is sharp. This value
must be >= 0.
*/
SK_API void sk_paint_set_stroke_miter(sk_paint_t*, float miter);
typedef enum {
BUTT_SK_STROKE_CAP,
ROUND_SK_STROKE_CAP,
SQUARE_SK_STROKE_CAP
} sk_stroke_cap_t;
/**
Return the paint's stroke cap type, controlling how the start and
end of stroked lines and paths are treated.
*/
SK_API sk_stroke_cap_t sk_paint_get_stroke_cap(const sk_paint_t*);
/**
Set the paint's stroke cap type, controlling how the start and
end of stroked lines and paths are treated.
*/
SK_API void sk_paint_set_stroke_cap(sk_paint_t*, sk_stroke_cap_t);
typedef enum {
MITER_SK_STROKE_JOIN,
ROUND_SK_STROKE_JOIN,
BEVEL_SK_STROKE_JOIN
} sk_stroke_join_t;
/**
Return the paint's stroke join type, specifies the treatment that
is applied to corners in paths and rectangles
*/
SK_API sk_stroke_join_t sk_paint_get_stroke_join(const sk_paint_t*);
/**
Set the paint's stroke join type, specifies the treatment that
is applied to corners in paths and rectangles
*/
SK_API void sk_paint_set_stroke_join(sk_paint_t*, sk_stroke_join_t);
/**
* Set the paint's shader to the specified parameter. This will automatically call unref() on
* any previous value, and call ref() on the new value.
*/
SK_API void sk_paint_set_shader(sk_paint_t*, sk_shader_t*);
/**
* Set the paint's maskfilter to the specified parameter. This will automatically call unref() on
* any previous value, and call ref() on the new value.
*/
SK_API void sk_paint_set_maskfilter(sk_paint_t*, sk_maskfilter_t*);
/**
* Set the paint's xfermode to the specified parameter.
*/
SK_API void sk_paint_set_xfermode_mode(sk_paint_t*, sk_xfermode_mode_t);
SK_C_PLUS_PLUS_END_GUARD
#endif

84
skia/include/c/sk_path.h vendored Normal file
View File

@ -0,0 +1,84 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL
// DO NOT USE -- FOR INTERNAL TESTING ONLY
#ifndef sk_path_DEFINED
#define sk_path_DEFINED
#include "sk_types.h"
SK_C_PLUS_PLUS_BEGIN_GUARD
typedef enum {
CW_SK_PATH_DIRECTION,
CCW_SK_PATH_DIRECTION,
} sk_path_direction_t;
/** Create a new, empty path. */
SK_API sk_path_t* sk_path_new(void);
/** Release the memory used by a sk_path_t. */
SK_API void sk_path_delete(sk_path_t*);
/** Set the beginning of the next contour to the point (x,y). */
SK_API void sk_path_move_to(sk_path_t*, float x, float y);
/**
Add a line from the last point to the specified point (x,y). If no
sk_path_move_to() call has been made for this contour, the first
point is automatically set to (0,0).
*/
SK_API void sk_path_line_to(sk_path_t*, float x, float y);
/**
Add a quadratic bezier from the last point, approaching control
point (x0,y0), and ending at (x1,y1). If no sk_path_move_to() call
has been made for this contour, the first point is automatically
set to (0,0).
*/
SK_API void sk_path_quad_to(sk_path_t*, float x0, float y0, float x1, float y1);
/**
Add a conic curve from the last point, approaching control point
(x0,y01), and ending at (x1,y1) with weight w. If no
sk_path_move_to() call has been made for this contour, the first
point is automatically set to (0,0).
*/
SK_API void sk_path_conic_to(sk_path_t*, float x0, float y0, float x1, float y1, float w);
/**
Add a cubic bezier from the last point, approaching control points
(x0,y0) and (x1,y1), and ending at (x2,y2). If no
sk_path_move_to() call has been made for this contour, the first
point is automatically set to (0,0).
*/
SK_API void sk_path_cubic_to(sk_path_t*,
float x0, float y0,
float x1, float y1,
float x2, float y2);
/**
Close the current contour. If the current point is not equal to the
first point of the contour, a line segment is automatically added.
*/
SK_API void sk_path_close(sk_path_t*);
/**
Add a closed rectangle contour to the path.
*/
SK_API void sk_path_add_rect(sk_path_t*, const sk_rect_t*, sk_path_direction_t);
/**
Add a closed oval contour to the path
*/
SK_API void sk_path_add_oval(sk_path_t*, const sk_rect_t*, sk_path_direction_t);
/**
* If the path is empty, return false and set the rect parameter to [0, 0, 0, 0].
* else return true and set the rect parameter to the bounds of the control-points
* of the path.
*/
SK_API bool sk_path_get_bounds(const sk_path_t*, sk_rect_t*);
SK_C_PLUS_PLUS_END_GUARD
#endif

70
skia/include/c/sk_picture.h vendored Normal file
View File

@ -0,0 +1,70 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL
// DO NOT USE -- FOR INTERNAL TESTING ONLY
#ifndef sk_picture_DEFINED
#define sk_picture_DEFINED
#include "sk_types.h"
SK_C_PLUS_PLUS_BEGIN_GUARD
/**
Create a new sk_picture_recorder_t. Its resources should be
released with a call to sk_picture_recorder_delete().
*/
sk_picture_recorder_t* sk_picture_recorder_new(void);
/**
Release the memory and other resources used by this
sk_picture_recorder_t.
*/
void sk_picture_recorder_delete(sk_picture_recorder_t*);
/**
Returns the canvas that records the drawing commands
@param sk_rect_t* the cull rect used when recording this
picture. Any drawing the falls outside of this
rect is undefined, and may be drawn or it may not.
*/
sk_canvas_t* sk_picture_recorder_begin_recording(sk_picture_recorder_t*, const sk_rect_t*);
/**
Signal that the caller is done recording. This invalidates the
canvas returned by begin_recording. Ownership of the sk_picture_t
is passed to the caller, who must call sk_picture_unref() when
they are done using it. The returned picture is immutable.
*/
sk_picture_t* sk_picture_recorder_end_recording(sk_picture_recorder_t*);
/**
Increment the reference count on the given sk_picture_t. Must be
balanced by a call to sk_picture_unref().
*/
void sk_picture_ref(sk_picture_t*);
/**
Decrement the reference count. If the reference count is 1 before
the decrement, then release both the memory holding the
sk_picture_t and any resouces it may be managing. New
sk_picture_t are created with a reference count of 1.
*/
void sk_picture_unref(sk_picture_t*);
/**
Returns a non-zero value unique among all pictures.
*/
uint32_t sk_picture_get_unique_id(sk_picture_t*);
/**
Return the cull rect specified when this picture was recorded.
*/
sk_rect_t sk_picture_get_bounds(sk_picture_t*);
SK_C_PLUS_PLUS_END_GUARD
#endif

143
skia/include/c/sk_shader.h vendored Normal file
View File

@ -0,0 +1,143 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL
// DO NOT USE -- FOR INTERNAL TESTING ONLY
#ifndef sk_shader_DEFINED
#define sk_shader_DEFINED
#include "sk_types.h"
SK_C_PLUS_PLUS_BEGIN_GUARD
void sk_shader_ref(sk_shader_t*);
void sk_shader_unref(sk_shader_t*);
typedef enum {
CLAMP_SK_SHADER_TILEMODE,
REPEAT_SK_SHADER_TILEMODE,
MIRROR_SK_SHADER_TILEMODE,
} sk_shader_tilemode_t;
/**
Returns a shader that generates a linear gradient between the two
specified points.
@param points The start and end points for the gradient.
@param colors The array[count] of colors, to be distributed between
the two points
@param colorPos May be NULL. array[count] of SkScalars, or NULL, of
the relative position of each corresponding color
in the colors array. If this is NULL, the the
colors are distributed evenly between the start
and end point. If this is not null, the values
must begin with 0, end with 1.0, and intermediate
values must be strictly increasing.
@param colorCount Must be >=2. The number of colors (and pos if not
NULL) entries.
@param mode The tiling mode
*/
sk_shader_t* sk_shader_new_linear_gradient(const sk_point_t points[2],
const sk_color_t colors[],
const float colorPos[],
int colorCount,
sk_shader_tilemode_t tileMode,
const sk_matrix_t* localMatrix);
/**
Returns a shader that generates a radial gradient given the center
and radius.
@param center The center of the circle for this gradient
@param radius Must be positive. The radius of the circle for this
gradient
@param colors The array[count] of colors, to be distributed
between the center and edge of the circle
@param colorPos May be NULL. The array[count] of the relative
position of each corresponding color in the colors
array. If this is NULL, the the colors are
distributed evenly between the center and edge of
the circle. If this is not null, the values must
begin with 0, end with 1.0, and intermediate
values must be strictly increasing.
@param count Must be >= 2. The number of colors (and pos if not
NULL) entries
@param tileMode The tiling mode
@param localMatrix May be NULL
*/
sk_shader_t* sk_shader_new_radial_gradient(const sk_point_t* center,
float radius,
const sk_color_t colors[],
const float colorPos[],
int colorCount,
sk_shader_tilemode_t tileMode,
const sk_matrix_t* localMatrix);
/**
Returns a shader that generates a sweep gradient given a center.
@param center The coordinates of the center of the sweep
@param colors The array[count] of colors, to be distributed around
the center.
@param colorPos May be NULL. The array[count] of the relative
position of each corresponding color in the colors
array. If this is NULL, the the colors are
distributed evenly between the center and edge of
the circle. If this is not null, the values must
begin with 0, end with 1.0, and intermediate
values must be strictly increasing.
@param colorCount Must be >= 2. The number of colors (and pos if
not NULL) entries
@param localMatrix May be NULL
*/
sk_shader_t* sk_shader_new_sweep_gradient(const sk_point_t* center,
const sk_color_t colors[],
const float colorPos[],
int colorCount,
const sk_matrix_t* localMatrix);
/**
Returns a shader that generates a conical gradient given two circles, or
returns NULL if the inputs are invalid. The gradient interprets the
two circles according to the following HTML spec.
http://dev.w3.org/html5/2dcontext/#dom-context-2d-createradialgradient
Returns a shader that generates a sweep gradient given a center.
@param start, startRadius Defines the first circle.
@param end, endRadius Defines the first circle.
@param colors The array[count] of colors, to be distributed between
the two circles.
@param colorPos May be NULL. The array[count] of the relative
position of each corresponding color in the colors
array. If this is NULL, the the colors are
distributed evenly between the two circles. If
this is not null, the values must begin with 0,
end with 1.0, and intermediate values must be
strictly increasing.
@param colorCount Must be >= 2. The number of colors (and pos if
not NULL) entries
@param tileMode The tiling mode
@param localMatrix May be NULL
*/
sk_shader_t* sk_shader_new_two_point_conical_gradient(
const sk_point_t* start,
float startRadius,
const sk_point_t* end,
float endRadius,
const sk_color_t colors[],
const float colorPos[],
int colorCount,
sk_shader_tilemode_t tileMode,
const sk_matrix_t* localMatrix);
SK_C_PLUS_PLUS_END_GUARD
#endif

73
skia/include/c/sk_surface.h vendored Normal file
View File

@ -0,0 +1,73 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL
// DO NOT USE -- FOR INTERNAL TESTING ONLY
#ifndef sk_surface_DEFINED
#define sk_surface_DEFINED
#include "sk_types.h"
SK_C_PLUS_PLUS_BEGIN_GUARD
/**
Return a new surface, with the memory for the pixels automatically
allocated. If the requested surface cannot be created, or the
request is not a supported configuration, NULL will be returned.
@param sk_imageinfo_t* Specify the width, height, color type, and
alpha type for the surface.
@param sk_surfaceprops_t* If not NULL, specify additional non-default
properties of the surface.
*/
SK_API sk_surface_t* sk_surface_new_raster(const sk_imageinfo_t*, const sk_surfaceprops_t*);
/**
Create a new surface which will draw into the specified pixels
with the specified rowbytes. If the requested surface cannot be
created, or the request is not a supported configuration, NULL
will be returned.
@param sk_imageinfo_t* Specify the width, height, color type, and
alpha type for the surface.
@param void* pixels Specify the location in memory where the
destination pixels are. This memory must
outlast this surface.
@param size_t rowBytes Specify the difference, in bytes, between
each adjacent row. Should be at least
(width * sizeof(one pixel)).
@param sk_surfaceprops_t* If not NULL, specify additional non-default
properties of the surface.
*/
SK_API sk_surface_t* sk_surface_new_raster_direct(const sk_imageinfo_t*,
void* pixels, size_t rowBytes,
const sk_surfaceprops_t* props);
/**
Decrement the reference count. If the reference count is 1 before
the decrement, then release both the memory holding the
sk_surface_t and any pixel memory it may be managing. New
sk_surface_t are created with a reference count of 1.
*/
SK_API void sk_surface_unref(sk_surface_t*);
/**
* Return the canvas associated with this surface. Note: the canvas is owned by the surface,
* so the returned object is only valid while the owning surface is valid.
*/
SK_API sk_canvas_t* sk_surface_get_canvas(sk_surface_t*);
/**
* Call sk_image_unref() when the returned image is no longer used.
*/
SK_API sk_image_t* sk_surface_new_image_snapshot(sk_surface_t*);
SK_C_PLUS_PLUS_END_GUARD
#endif

256
skia/include/c/sk_types.h vendored Normal file
View File

@ -0,0 +1,256 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL
// DO NOT USE -- FOR INTERNAL TESTING ONLY
#ifndef sk_types_DEFINED
#define sk_types_DEFINED
#include <stdint.h>
#include <stddef.h>
#ifdef __cplusplus
#define SK_C_PLUS_PLUS_BEGIN_GUARD extern "C" {
#define SK_C_PLUS_PLUS_END_GUARD }
#else
#include <stdbool.h>
#define SK_C_PLUS_PLUS_BEGIN_GUARD
#define SK_C_PLUS_PLUS_END_GUARD
#endif
#if !defined(SK_API)
#if defined(SKIA_DLL)
#if defined(_MSC_VER)
#if SKIA_IMPLEMENTATION
#define SK_API __declspec(dllexport)
#else
#define SK_API __declspec(dllimport)
#endif
#else
#define SK_API __attribute__((visibility("default")))
#endif
#else
#define SK_API
#endif
#endif
///////////////////////////////////////////////////////////////////////////////////////
SK_C_PLUS_PLUS_BEGIN_GUARD
typedef uint32_t sk_color_t;
/* This macro assumes all arguments are >=0 and <=255. */
#define sk_color_set_argb(a, r, g, b) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
#define sk_color_get_a(c) (((c) >> 24) & 0xFF)
#define sk_color_get_r(c) (((c) >> 16) & 0xFF)
#define sk_color_get_g(c) (((c) >> 8) & 0xFF)
#define sk_color_get_b(c) (((c) >> 0) & 0xFF)
typedef enum {
INTERSECT_SK_CLIPTYPE,
DIFFERENCE_SK_CLIPTYPE,
} sk_cliptype_t;
typedef enum {
UNKNOWN_SK_PIXELGEOMETRY,
RGB_H_SK_PIXELGEOMETRY,
BGR_H_SK_PIXELGEOMETRY,
RGB_V_SK_PIXELGEOMETRY,
BGR_V_SK_PIXELGEOMETRY,
} sk_pixelgeometry_t;
typedef struct {
sk_pixelgeometry_t pixelGeometry;
} sk_surfaceprops_t;
typedef struct {
float x;
float y;
} sk_point_t;
typedef struct {
int32_t left;
int32_t top;
int32_t right;
int32_t bottom;
} sk_irect_t;
typedef struct {
float left;
float top;
float right;
float bottom;
} sk_rect_t;
/**
The sk_matrix_t struct holds a 3x3 perspective matrix for
transforming coordinates:
(X,Y) = T[M]((x,y))
X = (M[0] * x + M[1] * y + M[2]) / (M[6] * x + M[7] * y + M[8]);
Y = (M[3] * x + M[4] * y + M[5]) / (M[6] * x + M[7] * y + M[8]);
Therefore, the identity matrix is
sk_matrix_t identity = {{1, 0, 0,
0, 1, 0,
0, 0, 1}};
A matrix that scales by sx and sy is:
sk_matrix_t scale = {{sx, 0, 0,
0, sy, 0,
0, 0, 1}};
A matrix that translates by tx and ty is:
sk_matrix_t translate = {{1, 0, tx,
0, 1, ty,
0, 0, 1}};
A matrix that rotates around the origin by A radians:
sk_matrix_t rotate = {{cos(A), -sin(A), 0,
sin(A), cos(A), 0,
0, 0, 1}};
Two matrixes can be concatinated by:
void concat_matrices(sk_matrix_t* dst,
const sk_matrix_t* matrixU,
const sk_matrix_t* matrixV) {
const float* u = matrixU->mat;
const float* v = matrixV->mat;
sk_matrix_t result = {{
u[0] * v[0] + u[1] * v[3] + u[2] * v[6],
u[0] * v[1] + u[1] * v[4] + u[2] * v[7],
u[0] * v[2] + u[1] * v[5] + u[2] * v[8],
u[3] * v[0] + u[4] * v[3] + u[5] * v[6],
u[3] * v[1] + u[4] * v[4] + u[5] * v[7],
u[3] * v[2] + u[4] * v[5] + u[5] * v[8],
u[6] * v[0] + u[7] * v[3] + u[8] * v[6],
u[6] * v[1] + u[7] * v[4] + u[8] * v[7],
u[6] * v[2] + u[7] * v[5] + u[8] * v[8]
}};
*dst = result;
}
*/
typedef struct {
float mat[9];
} sk_matrix_t;
/**
A sk_canvas_t encapsulates all of the state about drawing into a
destination This includes a reference to the destination itself,
and a stack of matrix/clip values.
*/
typedef struct sk_canvas_t sk_canvas_t;
/**
A sk_data_ holds an immutable data buffer.
*/
typedef struct sk_data_t sk_data_t;
/**
A sk_image_t is an abstraction for drawing a rectagle of pixels.
The content of the image is always immutable, though the actual
storage may change, if for example that image can be re-created via
encoded data or other means.
*/
typedef struct sk_image_t sk_image_t;
/**
* Describes the color components. See ICC Profiles.
*/
typedef struct sk_colorspace_t sk_colorspace_t;
/**
* Describes an image buffer : width, height, pixel type, colorspace, etc.
*/
typedef struct sk_imageinfo_t sk_imageinfo_t;
/**
A sk_maskfilter_t is an object that perform transformations on an
alpha-channel mask before drawing it; it may be installed into a
sk_paint_t. Each time a primitive is drawn, it is first
scan-converted into a alpha mask, which os handed to the
maskfilter, which may create a new mask is to render into the
destination.
*/
typedef struct sk_maskfilter_t sk_maskfilter_t;
/**
A sk_paint_t holds the style and color information about how to
draw geometries, text and bitmaps.
*/
typedef struct sk_paint_t sk_paint_t;
/**
A sk_path_t encapsulates compound (multiple contour) geometric
paths consisting of straight line segments, quadratic curves, and
cubic curves.
*/
typedef struct sk_path_t sk_path_t;
/**
A sk_picture_t holds recorded canvas drawing commands to be played
back at a later time.
*/
typedef struct sk_picture_t sk_picture_t;
/**
A sk_picture_recorder_t holds a sk_canvas_t that records commands
to create a sk_picture_t.
*/
typedef struct sk_picture_recorder_t sk_picture_recorder_t;
/**
A sk_shader_t specifies the source color(s) for what is being drawn. If a
paint has no shader, then the paint's color is used. If the paint
has a shader, then the shader's color(s) are use instead, but they
are modulated by the paint's alpha.
*/
typedef struct sk_shader_t sk_shader_t;
/**
A sk_surface_t holds the destination for drawing to a canvas. For
raster drawing, the destination is an array of pixels in memory.
For GPU drawing, the destination is a texture or a framebuffer.
*/
typedef struct sk_surface_t sk_surface_t;
typedef enum {
CLEAR_SK_XFERMODE_MODE,
SRC_SK_XFERMODE_MODE,
DST_SK_XFERMODE_MODE,
SRCOVER_SK_XFERMODE_MODE,
DSTOVER_SK_XFERMODE_MODE,
SRCIN_SK_XFERMODE_MODE,
DSTIN_SK_XFERMODE_MODE,
SRCOUT_SK_XFERMODE_MODE,
DSTOUT_SK_XFERMODE_MODE,
SRCATOP_SK_XFERMODE_MODE,
DSTATOP_SK_XFERMODE_MODE,
XOR_SK_XFERMODE_MODE,
PLUS_SK_XFERMODE_MODE,
MODULATE_SK_XFERMODE_MODE,
SCREEN_SK_XFERMODE_MODE,
OVERLAY_SK_XFERMODE_MODE,
DARKEN_SK_XFERMODE_MODE,
LIGHTEN_SK_XFERMODE_MODE,
COLORDODGE_SK_XFERMODE_MODE,
COLORBURN_SK_XFERMODE_MODE,
HARDLIGHT_SK_XFERMODE_MODE,
SOFTLIGHT_SK_XFERMODE_MODE,
DIFFERENCE_SK_XFERMODE_MODE,
EXCLUSION_SK_XFERMODE_MODE,
MULTIPLY_SK_XFERMODE_MODE,
HUE_SK_XFERMODE_MODE,
SATURATION_SK_XFERMODE_MODE,
COLOR_SK_XFERMODE_MODE,
LUMINOSITY_SK_XFERMODE_MODE,
} sk_xfermode_mode_t;
//////////////////////////////////////////////////////////////////////////////////////////
SK_C_PLUS_PLUS_END_GUARD
#endif

287
skia/include/codec/SkAndroidCodec.h vendored Normal file
View File

@ -0,0 +1,287 @@
/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkAndroidCodec_DEFINED
#define SkAndroidCodec_DEFINED
#include "SkCodec.h"
#include "SkEncodedImageFormat.h"
#include "SkStream.h"
#include "SkTypes.h"
/**
* Abstract interface defining image codec functionality that is necessary for
* Android.
*/
class SK_API SkAndroidCodec : SkNoncopyable {
public:
enum class ExifOrientationBehavior {
/**
* Ignore any exif orientation markers in the data.
*
* getInfo's width and height will match the header of the image, and
* no processing will be done to match the marker.
*/
kIgnore,
/**
* Respect the exif orientation marker.
*
* getInfo's width and height will represent what they should be after
* applying the orientation. For example, if the marker specifies a
* rotation by 90 degrees, they will be swapped relative to the header.
* getAndroidPixels will apply the orientation as well.
*/
kRespect,
};
/**
* Pass ownership of an SkCodec to a newly-created SkAndroidCodec.
*/
static std::unique_ptr<SkAndroidCodec> MakeFromCodec(std::unique_ptr<SkCodec>,
ExifOrientationBehavior = ExifOrientationBehavior::kIgnore);
/**
* If this stream represents an encoded image that we know how to decode,
* return an SkAndroidCodec that can decode it. Otherwise return NULL.
*
* The SkPngChunkReader handles unknown chunks in PNGs.
* See SkCodec.h for more details.
*
* If NULL is returned, the stream is deleted immediately. Otherwise, the
* SkCodec takes ownership of it, and will delete it when done with it.
*
* ExifOrientationBehavior is set to kIgnore.
*/
static std::unique_ptr<SkAndroidCodec> MakeFromStream(std::unique_ptr<SkStream>,
SkPngChunkReader* = nullptr);
/**
* If this data represents an encoded image that we know how to decode,
* return an SkAndroidCodec that can decode it. Otherwise return NULL.
*
* The SkPngChunkReader handles unknown chunks in PNGs.
* See SkCodec.h for more details.
*
* ExifOrientationBehavior is set to kIgnore.
*/
static std::unique_ptr<SkAndroidCodec> MakeFromData(sk_sp<SkData>, SkPngChunkReader* = nullptr);
virtual ~SkAndroidCodec();
const SkImageInfo& getInfo() const { return fInfo; }
/**
* Format of the encoded data.
*/
SkEncodedImageFormat getEncodedFormat() const { return fCodec->getEncodedFormat(); }
/**
* @param requestedColorType Color type requested by the client
*
* |requestedColorType| may be overriden. We will default to kF16
* for high precision images.
*
* In the general case, if it is possible to decode to
* |requestedColorType|, this returns |requestedColorType|.
* Otherwise, this returns a color type that is an appropriate
* match for the the encoded data.
*/
SkColorType computeOutputColorType(SkColorType requestedColorType);
/**
* @param requestedUnpremul Indicates if the client requested
* unpremultiplied output
*
* Returns the appropriate alpha type to decode to. If the image
* has alpha, the value of requestedUnpremul will be honored.
*/
SkAlphaType computeOutputAlphaType(bool requestedUnpremul);
/**
* @param outputColorType Color type that the client will decode to.
* @param prefColorSpace Preferred color space to decode to.
* This may not return |prefColorSpace| for a couple reasons.
* (1) Android Principles: 565 must be sRGB, F16 must be
* linear sRGB, transfer function must be parametric.
* (2) Codec Limitations: F16 requires a linear color space.
*
* Returns the appropriate color space to decode to.
*/
sk_sp<SkColorSpace> computeOutputColorSpace(SkColorType outputColorType,
sk_sp<SkColorSpace> prefColorSpace = nullptr);
/**
* Compute the appropriate sample size to get to |size|.
*
* @param size As an input parameter, the desired output size of
* the decode. As an output parameter, the smallest sampled size
* larger than the input.
* @return the sample size to set AndroidOptions::fSampleSize to decode
* to the output |size|.
*/
int computeSampleSize(SkISize* size) const;
/**
* Returns the dimensions of the scaled output image, for an input
* sampleSize.
*
* When the sample size divides evenly into the original dimensions, the
* scaled output dimensions will simply be equal to the original
* dimensions divided by the sample size.
*
* When the sample size does not divide even into the original
* dimensions, the codec may round up or down, depending on what is most
* efficient to decode.
*
* Finally, the codec will always recommend a non-zero output, so the output
* dimension will always be one if the sampleSize is greater than the
* original dimension.
*/
SkISize getSampledDimensions(int sampleSize) const;
/**
* Return (via desiredSubset) a subset which can decoded from this codec,
* or false if the input subset is invalid.
*
* @param desiredSubset in/out parameter
* As input, a desired subset of the original bounds
* (as specified by getInfo).
* As output, if true is returned, desiredSubset may
* have been modified to a subset which is
* supported. Although a particular change may have
* been made to desiredSubset to create something
* supported, it is possible other changes could
* result in a valid subset. If false is returned,
* desiredSubset's value is undefined.
* @return true If the input desiredSubset is valid.
* desiredSubset may be modified to a subset
* supported by the codec.
* false If desiredSubset is invalid (NULL or not fully
* contained within the image).
*/
bool getSupportedSubset(SkIRect* desiredSubset) const;
// TODO: Rename SkCodec::getValidSubset() to getSupportedSubset()
/**
* Returns the dimensions of the scaled, partial output image, for an
* input sampleSize and subset.
*
* @param sampleSize Factor to scale down by.
* @param subset Must be a valid subset of the original image
* dimensions and a subset supported by SkAndroidCodec.
* getSubset() can be used to obtain a subset supported
* by SkAndroidCodec.
* @return Size of the scaled partial image. Or zero size
* if either of the inputs is invalid.
*/
SkISize getSampledSubsetDimensions(int sampleSize, const SkIRect& subset) const;
/**
* Additional options to pass to getAndroidPixels().
*/
// FIXME: It's a bit redundant to name these AndroidOptions when this class is already
// called SkAndroidCodec. On the other hand, it's may be a bit confusing to call
// these Options when SkCodec has a slightly different set of Options. Maybe these
// should be DecodeOptions or SamplingOptions?
struct AndroidOptions {
AndroidOptions()
: fZeroInitialized(SkCodec::kNo_ZeroInitialized)
, fSubset(nullptr)
, fSampleSize(1)
{}
/**
* Indicates is destination pixel memory is zero initialized.
*
* The default is SkCodec::kNo_ZeroInitialized.
*/
SkCodec::ZeroInitialized fZeroInitialized;
/**
* If not NULL, represents a subset of the original image to decode.
*
* Must be within the bounds returned by getInfo().
*
* If the EncodedFormat is SkEncodedImageFormat::kWEBP, the top and left
* values must be even.
*
* The default is NULL, meaning a decode of the entire image.
*/
SkIRect* fSubset;
/**
* The client may provide an integer downscale factor for the decode.
* The codec may implement this downscaling by sampling or another
* method if it is more efficient.
*
* The default is 1, representing no downscaling.
*/
int fSampleSize;
};
/**
* Decode into the given pixels, a block of memory of size at
* least (info.fHeight - 1) * rowBytes + (info.fWidth *
* bytesPerPixel)
*
* Repeated calls to this function should give the same results,
* allowing the PixelRef to be immutable.
*
* @param info A description of the format (config, size)
* expected by the caller. This can simply be identical
* to the info returned by getInfo().
*
* This contract also allows the caller to specify
* different output-configs, which the implementation can
* decide to support or not.
*
* A size that does not match getInfo() implies a request
* to scale or subset. If the codec cannot perform this
* scaling or subsetting, it will return an error code.
*
* The AndroidOptions object is also used to specify any requested scaling or subsetting
* using options->fSampleSize and options->fSubset. If NULL, the defaults (as specified above
* for AndroidOptions) are used.
*
* @return Result kSuccess, or another value explaining the type of failure.
*/
// FIXME: It's a bit redundant to name this getAndroidPixels() when this class is already
// called SkAndroidCodec. On the other hand, it's may be a bit confusing to call
// this getPixels() when it is a slightly different API than SkCodec's getPixels().
// Maybe this should be decode() or decodeSubset()?
SkCodec::Result getAndroidPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
const AndroidOptions* options);
/**
* Simplified version of getAndroidPixels() where we supply the default AndroidOptions as
* specified above for AndroidOptions. It will not perform any scaling or subsetting.
*/
SkCodec::Result getAndroidPixels(const SkImageInfo& info, void* pixels, size_t rowBytes);
SkCodec::Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) {
return this->getAndroidPixels(info, pixels, rowBytes);
}
SkCodec* codec() const { return fCodec.get(); }
protected:
SkAndroidCodec(SkCodec*, ExifOrientationBehavior = ExifOrientationBehavior::kIgnore);
virtual SkISize onGetSampledDimensions(int sampleSize) const = 0;
virtual bool onGetSupportedSubset(SkIRect* desiredSubset) const = 0;
virtual SkCodec::Result onGetAndroidPixels(const SkImageInfo& info, void* pixels,
size_t rowBytes, const AndroidOptions& options) = 0;
private:
const SkImageInfo fInfo;
const ExifOrientationBehavior fOrientationBehavior;
std::unique_ptr<SkCodec> fCodec;
};
#endif // SkAndroidCodec_DEFINED

921
skia/include/codec/SkCodec.h vendored Normal file
View File

@ -0,0 +1,921 @@
/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkCodec_DEFINED
#define SkCodec_DEFINED
#include "../private/SkNoncopyable.h"
#include "../private/SkTemplates.h"
#include "../private/SkEncodedInfo.h"
#include "SkCodecAnimation.h"
#include "SkColor.h"
#include "SkEncodedImageFormat.h"
#include "SkEncodedOrigin.h"
#include "SkImageInfo.h"
#include "SkPixmap.h"
#include "SkSize.h"
#include "SkStream.h"
#include "SkTypes.h"
#include "SkYUVASizeInfo.h"
#include <vector>
class SkColorSpace;
class SkData;
class SkFrameHolder;
class SkPngChunkReader;
class SkSampler;
namespace DM {
class CodecSrc;
class ColorCodecSrc;
}
/**
* Abstraction layer directly on top of an image codec.
*/
class SK_API SkCodec : SkNoncopyable {
public:
/**
* Minimum number of bytes that must be buffered in SkStream input.
*
* An SkStream passed to NewFromStream must be able to use this many
* bytes to determine the image type. Then the same SkStream must be
* passed to the correct decoder to read from the beginning.
*
* This can be accomplished by implementing peek() to support peeking
* this many bytes, or by implementing rewind() to be able to rewind()
* after reading this many bytes.
*/
static constexpr size_t MinBufferedBytesNeeded() { return 32; }
/**
* Error codes for various SkCodec methods.
*/
enum Result {
/**
* General return value for success.
*/
kSuccess,
/**
* The input is incomplete. A partial image was generated.
*/
kIncompleteInput,
/**
* Like kIncompleteInput, except the input had an error.
*
* If returned from an incremental decode, decoding cannot continue,
* even with more data.
*/
kErrorInInput,
/**
* The generator cannot convert to match the request, ignoring
* dimensions.
*/
kInvalidConversion,
/**
* The generator cannot scale to requested size.
*/
kInvalidScale,
/**
* Parameters (besides info) are invalid. e.g. NULL pixels, rowBytes
* too small, etc.
*/
kInvalidParameters,
/**
* The input did not contain a valid image.
*/
kInvalidInput,
/**
* Fulfilling this request requires rewinding the input, which is not
* supported for this input.
*/
kCouldNotRewind,
/**
* An internal error, such as OOM.
*/
kInternalError,
/**
* This method is not implemented by this codec.
* FIXME: Perhaps this should be kUnsupported?
*/
kUnimplemented,
};
/**
* Readable string representing the error code.
*/
static const char* ResultToString(Result);
/**
* If this stream represents an encoded image that we know how to decode,
* return an SkCodec that can decode it. Otherwise return NULL.
*
* As stated above, this call must be able to peek or read
* MinBufferedBytesNeeded to determine the correct format, and then start
* reading from the beginning. First it will attempt to peek, and it
* assumes that if less than MinBufferedBytesNeeded bytes (but more than
* zero) are returned, this is because the stream is shorter than this,
* so falling back to reading would not provide more data. If peek()
* returns zero bytes, this call will instead attempt to read(). This
* will require that the stream can be rewind()ed.
*
* If Result is not NULL, it will be set to either kSuccess if an SkCodec
* is returned or a reason for the failure if NULL is returned.
*
* If SkPngChunkReader is not NULL, take a ref and pass it to libpng if
* the image is a png.
*
* If the SkPngChunkReader is not NULL then:
* If the image is not a PNG, the SkPngChunkReader will be ignored.
* If the image is a PNG, the SkPngChunkReader will be reffed.
* If the PNG has unknown chunks, the SkPngChunkReader will be used
* to handle these chunks. SkPngChunkReader will be called to read
* any unknown chunk at any point during the creation of the codec
* or the decode. Note that if SkPngChunkReader fails to read a
* chunk, this could result in a failure to create the codec or a
* failure to decode the image.
* If the PNG does not contain unknown chunks, the SkPngChunkReader
* will not be used or modified.
*
* If NULL is returned, the stream is deleted immediately. Otherwise, the
* SkCodec takes ownership of it, and will delete it when done with it.
*/
static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result* = nullptr,
SkPngChunkReader* = nullptr);
/**
* If this data represents an encoded image that we know how to decode,
* return an SkCodec that can decode it. Otherwise return NULL.
*
* If the SkPngChunkReader is not NULL then:
* If the image is not a PNG, the SkPngChunkReader will be ignored.
* If the image is a PNG, the SkPngChunkReader will be reffed.
* If the PNG has unknown chunks, the SkPngChunkReader will be used
* to handle these chunks. SkPngChunkReader will be called to read
* any unknown chunk at any point during the creation of the codec
* or the decode. Note that if SkPngChunkReader fails to read a
* chunk, this could result in a failure to create the codec or a
* failure to decode the image.
* If the PNG does not contain unknown chunks, the SkPngChunkReader
* will not be used or modified.
*/
static std::unique_ptr<SkCodec> MakeFromData(sk_sp<SkData>, SkPngChunkReader* = nullptr);
virtual ~SkCodec();
/**
* Return a reasonable SkImageInfo to decode into.
*/
SkImageInfo getInfo() const { return fEncodedInfo.makeImageInfo(); }
SkISize dimensions() const { return {fEncodedInfo.width(), fEncodedInfo.height()}; }
SkIRect bounds() const {
return SkIRect::MakeWH(fEncodedInfo.width(), fEncodedInfo.height());
}
/**
* Returns the image orientation stored in the EXIF data.
* If there is no EXIF data, or if we cannot read the EXIF data, returns kTopLeft.
*/
SkEncodedOrigin getOrigin() const { return fOrigin; }
/**
* Return a size that approximately supports the desired scale factor.
* The codec may not be able to scale efficiently to the exact scale
* factor requested, so return a size that approximates that scale.
* The returned value is the codec's suggestion for the closest valid
* scale that it can natively support
*/
SkISize getScaledDimensions(float desiredScale) const {
// Negative and zero scales are errors.
SkASSERT(desiredScale > 0.0f);
if (desiredScale <= 0.0f) {
return SkISize::Make(0, 0);
}
// Upscaling is not supported. Return the original size if the client
// requests an upscale.
if (desiredScale >= 1.0f) {
return this->dimensions();
}
return this->onGetScaledDimensions(desiredScale);
}
/**
* Return (via desiredSubset) a subset which can decoded from this codec,
* or false if this codec cannot decode subsets or anything similar to
* desiredSubset.
*
* @param desiredSubset In/out parameter. As input, a desired subset of
* the original bounds (as specified by getInfo). If true is returned,
* desiredSubset may have been modified to a subset which is
* supported. Although a particular change may have been made to
* desiredSubset to create something supported, it is possible other
* changes could result in a valid subset.
* If false is returned, desiredSubset's value is undefined.
* @return true if this codec supports decoding desiredSubset (as
* returned, potentially modified)
*/
bool getValidSubset(SkIRect* desiredSubset) const {
return this->onGetValidSubset(desiredSubset);
}
/**
* Format of the encoded data.
*/
SkEncodedImageFormat getEncodedFormat() const { return this->onGetEncodedFormat(); }
/**
* Whether or not the memory passed to getPixels is zero initialized.
*/
enum ZeroInitialized {
/**
* The memory passed to getPixels is zero initialized. The SkCodec
* may take advantage of this by skipping writing zeroes.
*/
kYes_ZeroInitialized,
/**
* The memory passed to getPixels has not been initialized to zero,
* so the SkCodec must write all zeroes to memory.
*
* This is the default. It will be used if no Options struct is used.
*/
kNo_ZeroInitialized,
};
/**
* Additional options to pass to getPixels.
*/
struct Options {
Options()
: fZeroInitialized(kNo_ZeroInitialized)
, fSubset(nullptr)
, fFrameIndex(0)
, fPriorFrame(kNoFrame)
{}
ZeroInitialized fZeroInitialized;
/**
* If not NULL, represents a subset of the original image to decode.
* Must be within the bounds returned by getInfo().
* If the EncodedFormat is SkEncodedImageFormat::kWEBP (the only one which
* currently supports subsets), the top and left values must be even.
*
* In getPixels and incremental decode, we will attempt to decode the
* exact rectangular subset specified by fSubset.
*
* In a scanline decode, it does not make sense to specify a subset
* top or subset height, since the client already controls which rows
* to get and which rows to skip. During scanline decodes, we will
* require that the subset top be zero and the subset height be equal
* to the full height. We will, however, use the values of
* subset left and subset width to decode partial scanlines on calls
* to getScanlines().
*/
const SkIRect* fSubset;
/**
* The frame to decode.
*
* Only meaningful for multi-frame images.
*/
int fFrameIndex;
/**
* If not kNoFrame, the dst already contains the prior frame at this index.
*
* Only meaningful for multi-frame images.
*
* If fFrameIndex needs to be blended with a prior frame (as reported by
* getFrameInfo[fFrameIndex].fRequiredFrame), the client can set this to
* any non-kRestorePrevious frame in [fRequiredFrame, fFrameIndex) to
* indicate that that frame is already in the dst. Options.fZeroInitialized
* is ignored in this case.
*
* If set to kNoFrame, the codec will decode any necessary required frame(s) first.
*/
int fPriorFrame;
};
/**
* Decode into the given pixels, a block of memory of size at
* least (info.fHeight - 1) * rowBytes + (info.fWidth *
* bytesPerPixel)
*
* Repeated calls to this function should give the same results,
* allowing the PixelRef to be immutable.
*
* @param info A description of the format (config, size)
* expected by the caller. This can simply be identical
* to the info returned by getInfo().
*
* This contract also allows the caller to specify
* different output-configs, which the implementation can
* decide to support or not.
*
* A size that does not match getInfo() implies a request
* to scale. If the generator cannot perform this scale,
* it will return kInvalidScale.
*
* If the info contains a non-null SkColorSpace, the codec
* will perform the appropriate color space transformation.
* If the caller passes in the same color space that was
* reported by the codec, the color space transformation is
* a no-op.
*
* If a scanline decode is in progress, scanline mode will end, requiring the client to call
* startScanlineDecode() in order to return to decoding scanlines.
*
* @return Result kSuccess, or another value explaining the type of failure.
*/
Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const Options*);
/**
* Simplified version of getPixels() that uses the default Options.
*/
Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) {
return this->getPixels(info, pixels, rowBytes, nullptr);
}
Result getPixels(const SkPixmap& pm, const Options* opts = nullptr) {
return this->getPixels(pm.info(), pm.writable_addr(), pm.rowBytes(), opts);
}
/**
* If decoding to YUV is supported, this returns true. Otherwise, this
* returns false and does not modify any of the parameters.
*
* @param sizeInfo Output parameter indicating the sizes and required
* allocation widths of the Y, U, V, and A planes. Given current codec
* limitations the size of the A plane will always be 0 and the Y, U, V
* channels will always be planar.
* @param colorSpace Output parameter. If non-NULL this is set to kJPEG,
* otherwise this is ignored.
*/
bool queryYUV8(SkYUVASizeInfo* sizeInfo, SkYUVColorSpace* colorSpace) const {
if (nullptr == sizeInfo) {
return false;
}
bool result = this->onQueryYUV8(sizeInfo, colorSpace);
if (result) {
for (int i = 0; i <= 2; ++i) {
SkASSERT(sizeInfo->fSizes[i].fWidth > 0 && sizeInfo->fSizes[i].fHeight > 0 &&
sizeInfo->fWidthBytes[i] > 0);
}
SkASSERT(!sizeInfo->fSizes[3].fWidth &&
!sizeInfo->fSizes[3].fHeight &&
!sizeInfo->fWidthBytes[3]);
}
return result;
}
/**
* Returns kSuccess, or another value explaining the type of failure.
* This always attempts to perform a full decode. If the client only
* wants size, it should call queryYUV8().
*
* @param sizeInfo Needs to exactly match the values returned by the
* query, except the WidthBytes may be larger than the
* recommendation (but not smaller).
* @param planes Memory for each of the Y, U, and V planes.
*/
Result getYUV8Planes(const SkYUVASizeInfo& sizeInfo, void* planes[SkYUVASizeInfo::kMaxCount]) {
if (!planes || !planes[0] || !planes[1] || !planes[2]) {
return kInvalidInput;
}
SkASSERT(!planes[3]); // TODO: is this a fair assumption?
if (!this->rewindIfNeeded()) {
return kCouldNotRewind;
}
return this->onGetYUV8Planes(sizeInfo, planes);
}
/**
* Prepare for an incremental decode with the specified options.
*
* This may require a rewind.
*
* @param dstInfo Info of the destination. If the dimensions do not match
* those of getInfo, this implies a scale.
* @param dst Memory to write to. Needs to be large enough to hold the subset,
* if present, or the full image as described in dstInfo.
* @param options Contains decoding options, including if memory is zero
* initialized and whether to decode a subset.
* @return Enum representing success or reason for failure.
*/
Result startIncrementalDecode(const SkImageInfo& dstInfo, void* dst, size_t rowBytes,
const Options*);
Result startIncrementalDecode(const SkImageInfo& dstInfo, void* dst, size_t rowBytes) {
return this->startIncrementalDecode(dstInfo, dst, rowBytes, nullptr);
}
/**
* Start/continue the incremental decode.
*
* Not valid to call before calling startIncrementalDecode().
*
* After the first call, should only be called again if more data has been
* provided to the source SkStream.
*
* Unlike getPixels and getScanlines, this does not do any filling. This is
* left up to the caller, since they may be skipping lines or continuing the
* decode later. In the latter case, they may choose to initialize all lines
* first, or only initialize the remaining lines after the first call.
*
* @param rowsDecoded Optional output variable returning the total number of
* lines initialized. Only meaningful if this method returns kIncompleteInput.
* Otherwise the implementation may not set it.
* Note that some implementations may have initialized this many rows, but
* not necessarily finished those rows (e.g. interlaced PNG). This may be
* useful for determining what rows the client needs to initialize.
* @return kSuccess if all lines requested in startIncrementalDecode have
* been completely decoded. kIncompleteInput otherwise.
*/
Result incrementalDecode(int* rowsDecoded = nullptr) {
if (!fStartedIncrementalDecode) {
return kInvalidParameters;
}
return this->onIncrementalDecode(rowsDecoded);
}
/**
* The remaining functions revolve around decoding scanlines.
*/
/**
* Prepare for a scanline decode with the specified options.
*
* After this call, this class will be ready to decode the first scanline.
*
* This must be called in order to call getScanlines or skipScanlines.
*
* This may require rewinding the stream.
*
* Not all SkCodecs support this.
*
* @param dstInfo Info of the destination. If the dimensions do not match
* those of getInfo, this implies a scale.
* @param options Contains decoding options, including if memory is zero
* initialized.
* @return Enum representing success or reason for failure.
*/
Result startScanlineDecode(const SkImageInfo& dstInfo, const Options* options);
/**
* Simplified version of startScanlineDecode() that uses the default Options.
*/
Result startScanlineDecode(const SkImageInfo& dstInfo) {
return this->startScanlineDecode(dstInfo, nullptr);
}
/**
* Write the next countLines scanlines into dst.
*
* Not valid to call before calling startScanlineDecode().
*
* @param dst Must be non-null, and large enough to hold countLines
* scanlines of size rowBytes.
* @param countLines Number of lines to write.
* @param rowBytes Number of bytes per row. Must be large enough to hold
* a scanline based on the SkImageInfo used to create this object.
* @return the number of lines successfully decoded. If this value is
* less than countLines, this will fill the remaining lines with a
* default value.
*/
int getScanlines(void* dst, int countLines, size_t rowBytes);
/**
* Skip count scanlines.
*
* Not valid to call before calling startScanlineDecode().
*
* The default version just calls onGetScanlines and discards the dst.
* NOTE: If skipped lines are the only lines with alpha, this default
* will make reallyHasAlpha return true, when it could have returned
* false.
*
* @return true if the scanlines were successfully skipped
* false on failure, possible reasons for failure include:
* An incomplete input image stream.
* Calling this function before calling startScanlineDecode().
* If countLines is less than zero or so large that it moves
* the current scanline past the end of the image.
*/
bool skipScanlines(int countLines);
/**
* The order in which rows are output from the scanline decoder is not the
* same for all variations of all image types. This explains the possible
* output row orderings.
*/
enum SkScanlineOrder {
/*
* By far the most common, this indicates that the image can be decoded
* reliably using the scanline decoder, and that rows will be output in
* the logical order.
*/
kTopDown_SkScanlineOrder,
/*
* This indicates that the scanline decoder reliably outputs rows, but
* they will be returned in reverse order. If the scanline format is
* kBottomUp, the nextScanline() API can be used to determine the actual
* y-coordinate of the next output row, but the client is not forced
* to take advantage of this, given that it's not too tough to keep
* track independently.
*
* For full image decodes, it is safe to get all of the scanlines at
* once, since the decoder will handle inverting the rows as it
* decodes.
*
* For subset decodes and sampling, it is simplest to get and skip
* scanlines one at a time, using the nextScanline() API. It is
* possible to ask for larger chunks at a time, but this should be used
* with caution. As with full image decodes, the decoder will handle
* inverting the requested rows, but rows will still be delivered
* starting from the bottom of the image.
*
* Upside down bmps are an example.
*/
kBottomUp_SkScanlineOrder,
};
/**
* An enum representing the order in which scanlines will be returned by
* the scanline decoder.
*
* This is undefined before startScanlineDecode() is called.
*/
SkScanlineOrder getScanlineOrder() const { return this->onGetScanlineOrder(); }
/**
* Returns the y-coordinate of the next row to be returned by the scanline
* decoder.
*
* This will equal fCurrScanline, except in the case of strangely
* encoded image types (bottom-up bmps).
*
* Results are undefined when not in scanline decoding mode.
*/
int nextScanline() const { return this->outputScanline(fCurrScanline); }
/**
* Returns the output y-coordinate of the row that corresponds to an input
* y-coordinate. The input y-coordinate represents where the scanline
* is located in the encoded data.
*
* This will equal inputScanline, except in the case of strangely
* encoded image types (bottom-up bmps, interlaced gifs).
*/
int outputScanline(int inputScanline) const;
/**
* Return the number of frames in the image.
*
* May require reading through the stream.
*/
int getFrameCount() {
return this->onGetFrameCount();
}
// Sentinel value used when a frame index implies "no frame":
// - FrameInfo::fRequiredFrame set to this value means the frame
// is independent.
// - Options::fPriorFrame set to this value means no (relevant) prior frame
// is residing in dst's memory.
static constexpr int kNoFrame = -1;
// This transitional definition was added in August 2018, and will eventually be removed.
#ifdef SK_LEGACY_SKCODEC_NONE_ENUM
static constexpr int kNone = kNoFrame;
#endif
/**
* Information about individual frames in a multi-framed image.
*/
struct FrameInfo {
/**
* The frame that this frame needs to be blended with, or
* kNoFrame if this frame is independent.
*
* Note that this is the *earliest* frame that can be used
* for blending. Any frame from [fRequiredFrame, i) can be
* used, unless its fDisposalMethod is kRestorePrevious.
*/
int fRequiredFrame;
/**
* Number of milliseconds to show this frame.
*/
int fDuration;
/**
* Whether the end marker for this frame is contained in the stream.
*
* Note: this does not guarantee that an attempt to decode will be complete.
* There could be an error in the stream.
*/
bool fFullyReceived;
/**
* This is conservative; it will still return non-opaque if e.g. a
* color index-based frame has a color with alpha but does not use it.
*/
SkAlphaType fAlphaType;
/**
* How this frame should be modified before decoding the next one.
*/
SkCodecAnimation::DisposalMethod fDisposalMethod;
};
/**
* Return info about a single frame.
*
* Only supported by multi-frame images. Does not read through the stream,
* so it should be called after getFrameCount() to parse any frames that
* have not already been parsed.
*/
bool getFrameInfo(int index, FrameInfo* info) const {
if (index < 0) {
return false;
}
return this->onGetFrameInfo(index, info);
}
/**
* Return info about all the frames in the image.
*
* May require reading through the stream to determine info about the
* frames (including the count).
*
* As such, future decoding calls may require a rewind.
*
* For still (non-animated) image codecs, this will return an empty vector.
*/
std::vector<FrameInfo> getFrameInfo();
static constexpr int kRepetitionCountInfinite = -1;
/**
* Return the number of times to repeat, if this image is animated. This number does not
* include the first play through of each frame. For example, a repetition count of 4 means
* that each frame is played 5 times and then the animation stops.
*
* It can return kRepetitionCountInfinite, a negative number, meaning that the animation
* should loop forever.
*
* May require reading the stream to find the repetition count.
*
* As such, future decoding calls may require a rewind.
*
* For still (non-animated) image codecs, this will return 0.
*/
int getRepetitionCount() {
return this->onGetRepetitionCount();
}
protected:
const SkEncodedInfo& getEncodedInfo() const { return fEncodedInfo; }
using XformFormat = skcms_PixelFormat;
SkCodec(SkEncodedInfo&&,
XformFormat srcFormat,
std::unique_ptr<SkStream>,
SkEncodedOrigin = kTopLeft_SkEncodedOrigin);
virtual SkISize onGetScaledDimensions(float /*desiredScale*/) const {
// By default, scaling is not supported.
return this->dimensions();
}
// FIXME: What to do about subsets??
/**
* Subclasses should override if they support dimensions other than the
* srcInfo's.
*/
virtual bool onDimensionsSupported(const SkISize&) {
return false;
}
virtual SkEncodedImageFormat onGetEncodedFormat() const = 0;
/**
* @param rowsDecoded When the encoded image stream is incomplete, this function
* will return kIncompleteInput and rowsDecoded will be set to
* the number of scanlines that were successfully decoded.
* This will allow getPixels() to fill the uninitialized memory.
*/
virtual Result onGetPixels(const SkImageInfo& info,
void* pixels, size_t rowBytes, const Options&,
int* rowsDecoded) = 0;
virtual bool onQueryYUV8(SkYUVASizeInfo*, SkYUVColorSpace*) const {
return false;
}
virtual Result onGetYUV8Planes(const SkYUVASizeInfo&,
void*[SkYUVASizeInfo::kMaxCount] /*planes*/) {
return kUnimplemented;
}
virtual bool onGetValidSubset(SkIRect* /*desiredSubset*/) const {
// By default, subsets are not supported.
return false;
}
/**
* If the stream was previously read, attempt to rewind.
*
* If the stream needed to be rewound, call onRewind.
* @returns true if the codec is at the right position and can be used.
* false if there was a failure to rewind.
*
* This is called by getPixels(), getYUV8Planes(), startIncrementalDecode() and
* startScanlineDecode(). Subclasses may call if they need to rewind at another time.
*/
bool SK_WARN_UNUSED_RESULT rewindIfNeeded();
/**
* Called by rewindIfNeeded, if the stream needed to be rewound.
*
* Subclasses should do any set up needed after a rewind.
*/
virtual bool onRewind() {
return true;
}
/**
* Get method for the input stream
*/
SkStream* stream() {
return fStream.get();
}
/**
* The remaining functions revolve around decoding scanlines.
*/
/**
* Most images types will be kTopDown and will not need to override this function.
*/
virtual SkScanlineOrder onGetScanlineOrder() const { return kTopDown_SkScanlineOrder; }
const SkImageInfo& dstInfo() const { return fDstInfo; }
const Options& options() const { return fOptions; }
/**
* Returns the number of scanlines that have been decoded so far.
* This is unaffected by the SkScanlineOrder.
*
* Returns -1 if we have not started a scanline decode.
*/
int currScanline() const { return fCurrScanline; }
virtual int onOutputScanline(int inputScanline) const;
/**
* Return whether we can convert to dst.
*
* Will be called for the appropriate frame, prior to initializing the colorXform.
*/
virtual bool conversionSupported(const SkImageInfo& dst, bool srcIsOpaque,
bool needsColorXform);
// Some classes never need a colorXform e.g.
// - ICO uses its embedded codec's colorXform
// - WBMP is just Black/White
virtual bool usesColorXform() const { return true; }
void applyColorXform(void* dst, const void* src, int count) const;
bool colorXform() const { return fXformTime != kNo_XformTime; }
bool xformOnDecode() const { return fXformTime == kDecodeRow_XformTime; }
virtual int onGetFrameCount() {
return 1;
}
virtual bool onGetFrameInfo(int, FrameInfo*) const {
return false;
}
virtual int onGetRepetitionCount() {
return 0;
}
private:
const SkEncodedInfo fEncodedInfo;
const XformFormat fSrcXformFormat;
std::unique_ptr<SkStream> fStream;
bool fNeedsRewind;
const SkEncodedOrigin fOrigin;
SkImageInfo fDstInfo;
Options fOptions;
enum XformTime {
kNo_XformTime,
kPalette_XformTime,
kDecodeRow_XformTime,
};
XformTime fXformTime;
XformFormat fDstXformFormat; // Based on fDstInfo.
skcms_ICCProfile fDstProfile;
skcms_AlphaFormat fDstXformAlphaFormat;
// Only meaningful during scanline decodes.
int fCurrScanline;
bool fStartedIncrementalDecode;
bool initializeColorXform(const SkImageInfo& dstInfo, SkEncodedInfo::Alpha, bool srcIsOpaque);
/**
* Return whether these dimensions are supported as a scale.
*
* The codec may choose to cache the information about scale and subset.
* Either way, the same information will be passed to onGetPixels/onStart
* on success.
*
* This must return true for a size returned from getScaledDimensions.
*/
bool dimensionsSupported(const SkISize& dim) {
return dim == this->dimensions() || this->onDimensionsSupported(dim);
}
/**
* For multi-framed images, return the object with information about the frames.
*/
virtual const SkFrameHolder* getFrameHolder() const {
return nullptr;
}
/**
* Check for a valid Options.fFrameIndex, and decode prior frames if necessary.
*/
Result handleFrameIndex(const SkImageInfo&, void* pixels, size_t rowBytes, const Options&);
// Methods for scanline decoding.
virtual Result onStartScanlineDecode(const SkImageInfo& /*dstInfo*/,
const Options& /*options*/) {
return kUnimplemented;
}
virtual Result onStartIncrementalDecode(const SkImageInfo& /*dstInfo*/, void*, size_t,
const Options&) {
return kUnimplemented;
}
virtual Result onIncrementalDecode(int*) {
return kUnimplemented;
}
virtual bool onSkipScanlines(int /*countLines*/) { return false; }
virtual int onGetScanlines(void* /*dst*/, int /*countLines*/, size_t /*rowBytes*/) { return 0; }
/**
* On an incomplete decode, getPixels() and getScanlines() will call this function
* to fill any uinitialized memory.
*
* @param dstInfo Contains the destination color type
* Contains the destination alpha type
* Contains the destination width
* The height stored in this info is unused
* @param dst Pointer to the start of destination pixel memory
* @param rowBytes Stride length in destination pixel memory
* @param zeroInit Indicates if memory is zero initialized
* @param linesRequested Number of lines that the client requested
* @param linesDecoded Number of lines that were successfully decoded
*/
void fillIncompleteImage(const SkImageInfo& dstInfo, void* dst, size_t rowBytes,
ZeroInitialized zeroInit, int linesRequested, int linesDecoded);
/**
* Return an object which will allow forcing scanline decodes to sample in X.
*
* May create a sampler, if one is not currently being used. Otherwise, does
* not affect ownership.
*
* Only valid during scanline decoding or incremental decoding.
*/
virtual SkSampler* getSampler(bool /*createIfNecessary*/) { return nullptr; }
friend class DM::CodecSrc; // for fillIncompleteImage
friend class SkSampledCodec;
friend class SkIcoCodec;
friend class SkAndroidCodec; // for fEncodedInfo
};
#endif // SkCodec_DEFINED

43
skia/include/codec/SkCodecAnimation.h vendored Normal file
View File

@ -0,0 +1,43 @@
/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkCodecAnimation_DEFINED
#define SkCodecAnimation_DEFINED
namespace SkCodecAnimation {
/**
* This specifies how the next frame is based on this frame.
*
* Names are based on the GIF 89a spec.
*
* The numbers correspond to values in a GIF.
*/
enum class DisposalMethod {
/**
* The next frame should be drawn on top of this one.
*
* In a GIF, a value of 0 (not specified) is also treated as Keep.
*/
kKeep = 1,
/**
* Similar to Keep, except the area inside this frame's rectangle
* should be cleared to the BackGround color (transparent) before
* drawing the next frame.
*/
kRestoreBGColor = 2,
/**
* The next frame should be drawn on top of the previous frame - i.e.
* disregarding this one.
*
* In a GIF, a value of 4 is also treated as RestorePrevious.
*/
kRestorePrevious = 3,
};
};
#endif // SkCodecAnimation_DEFINED

23
skia/include/codec/SkEncodedOrigin.h vendored Normal file
View File

@ -0,0 +1,23 @@
/*
* Copyright 2017 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkEncodedOrigin_DEFINED
#define SkEncodedOrigin_DEFINED
// These values match the orientation www.exif.org/Exif2-2.PDF.
enum SkEncodedOrigin {
kTopLeft_SkEncodedOrigin = 1, // Default
kTopRight_SkEncodedOrigin = 2, // Reflected across y-axis
kBottomRight_SkEncodedOrigin = 3, // Rotated 180
kBottomLeft_SkEncodedOrigin = 4, // Reflected across x-axis
kLeftTop_SkEncodedOrigin = 5, // Reflected across x-axis, Rotated 90 CCW
kRightTop_SkEncodedOrigin = 6, // Rotated 90 CW
kRightBottom_SkEncodedOrigin = 7, // Reflected across x-axis, Rotated 90 CW
kLeftBottom_SkEncodedOrigin = 8, // Rotated 90 CCW
kDefault_SkEncodedOrigin = kTopLeft_SkEncodedOrigin,
kLast_SkEncodedOrigin = kLeftBottom_SkEncodedOrigin,
};
#endif // SkEncodedOrigin_DEFINED

130
skia/include/config/SkUserConfig.h vendored Normal file
View File

@ -0,0 +1,130 @@
/*
* Copyright 2006 The Android Open Source Project
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkUserConfig_DEFINED
#define SkUserConfig_DEFINED
/* SkTypes.h, the root of the public header files, 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.
*/
///////////////////////////////////////////////////////////////////////////////
/* 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
/* Skia has certain debug-only code that is extremely intensive even for debug
builds. This code is useful for diagnosing specific issues, but is not
generally applicable, therefore it must be explicitly enabled to avoid
the performance impact. By default these flags are undefined, but can be
enabled by uncommenting them below.
*/
//#define SK_DEBUG_GLYPH_CACHE
//#define SK_DEBUG_PATH
/* 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
/* Most compilers use the same bit endianness for bit flags in a byte as the
system byte endianness, and this is the default. If for some reason this
needs to be overridden, specify which of the mutually exclusive flags to
use. For example, some atom processors in certain configurations have big
endian byte order but little endian bit orders.
*/
//#define SK_UINT8_BITFIELD_BENDIAN
//#define SK_UINT8_BITFIELD_LENDIAN
/* 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__)
/*
* To specify a different default font cache limit, define this. If this is
* undefined, skia will use a built-in value.
*/
//#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)
/* Define this to set the upper limit for text to support LCD. Values that
are very large increase the cost in the font cache and draw slower, without
improving readability. If this is undefined, Skia will use its default
value (e.g. 48)
*/
//#define SK_MAX_SIZE_FOR_LCDTEXT 48
/* Change the ordering to work in X windows.
*/
#ifdef SK_SAMPLES_FOR_X
#define SK_R32_SHIFT 16
#define SK_G32_SHIFT 8
#define SK_B32_SHIFT 0
#define SK_A32_SHIFT 24
#endif
/* Determines whether to build code that supports the GPU backend. Some classes
that are not GPU-specific, such as SkShader subclasses, have optional code
that is used allows them to interact with the GPU backend. If you'd like to
omit this code set SK_SUPPORT_GPU to 0. This also allows you to omit the gpu
directories from your include search path when you're not building the GPU
backend. Defaults to 1 (build the GPU code).
*/
//#define SK_SUPPORT_GPU 1
/* Skia makes use of histogram logging macros to trace the frequency of
* events. By default, Skia provides no-op versions of these macros.
* Skia consumers can provide their own definitions of these macros to
* integrate with their histogram collection backend.
*/
//#define SK_HISTOGRAM_BOOLEAN(name, value)
//#define SK_HISTOGRAM_ENUMERATION(name, value, boundary_value)
#endif

50
skia/include/core/SkAnnotation.h vendored Normal file
View File

@ -0,0 +1,50 @@
/*
* Copyright 2012 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkAnnotation_DEFINED
#define SkAnnotation_DEFINED
#include "SkTypes.h"
class SkData;
struct SkPoint;
struct SkRect;
class SkCanvas;
/**
* Annotate the canvas by associating the specified URL with the
* specified rectangle (in local coordinates, just like drawRect).
*
* If the backend of this canvas does not support annotations, this call is
* safely ignored.
*
* The caller is responsible for managing its ownership of the SkData.
*/
SK_API void SkAnnotateRectWithURL(SkCanvas*, const SkRect&, SkData*);
/**
* Annotate the canvas by associating a name with the specified point.
*
* If the backend of this canvas does not support annotations, this call is
* safely ignored.
*
* The caller is responsible for managing its ownership of the SkData.
*/
SK_API void SkAnnotateNamedDestination(SkCanvas*, const SkPoint&, SkData*);
/**
* Annotate the canvas by making the specified rectangle link to a named
* destination.
*
* If the backend of this canvas does not support annotations, this call is
* safely ignored.
*
* The caller is responsible for managing its ownership of the SkData.
*/
SK_API void SkAnnotateLinkToDestination(SkCanvas*, const SkRect&, SkData*);
#endif

31
skia/include/core/SkBBHFactory.h vendored Normal file
View File

@ -0,0 +1,31 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkBBHFactory_DEFINED
#define SkBBHFactory_DEFINED
#include "SkTypes.h"
class SkBBoxHierarchy;
struct SkRect;
class SK_API SkBBHFactory {
public:
/**
* Allocate a new SkBBoxHierarchy. Return NULL on failure.
*/
virtual SkBBoxHierarchy* operator()(const SkRect& bounds) const = 0;
virtual ~SkBBHFactory() {}
};
class SK_API SkRTreeFactory : public SkBBHFactory {
public:
SkBBoxHierarchy* operator()(const SkRect& bounds) const override;
private:
typedef SkBBHFactory INHERITED;
};
#endif

1195
skia/include/core/SkBitmap.h vendored Normal file

File diff suppressed because it is too large Load Diff

75
skia/include/core/SkBlendMode.h vendored Normal file
View File

@ -0,0 +1,75 @@
/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/* Generated by tools/bookmaker from include/core/SkBlendMode.h and docs/SkBlendMode_Reference.bmh
on 2018-07-13 08:15:10. Additional documentation and examples can be found at:
https://skia.org/user/api/SkBlendMode_Reference
You may edit either file directly. Structural changes to public interfaces require
editing both files. After editing docs/SkBlendMode_Reference.bmh, run:
bookmaker -b docs -i include/core/SkBlendMode.h -p
to create an updated version of this file.
*/
#ifndef SkBlendMode_DEFINED
#define SkBlendMode_DEFINED
#include "SkTypes.h"
enum class SkBlendMode {
kClear, //!< replaces destination with zero: fully transparent
kSrc, //!< replaces destination
kDst, //!< preserves destination
kSrcOver, //!< source over destination
kDstOver, //!< destination over source
kSrcIn, //!< source trimmed inside destination
kDstIn, //!< destination trimmed by source
kSrcOut, //!< source trimmed outside destination
kDstOut, //!< destination trimmed outside source
kSrcATop, //!< source inside destination blended with destination
kDstATop, //!< destination inside source blended with source
kXor, //!< each of source and destination trimmed outside the other
kPlus, //!< sum of colors
kModulate, //!< product of premultiplied colors; darkens destination
kScreen, //!< multiply inverse of pixels, inverting result; brightens destination
kLastCoeffMode = kScreen, //!< last porter duff blend mode
kOverlay, //!< multiply or screen, depending on destination
kDarken, //!< darker of source and destination
kLighten, //!< lighter of source and destination
kColorDodge, //!< brighten destination to reflect source
kColorBurn, //!< darken destination to reflect source
kHardLight, //!< multiply or screen, depending on source
kSoftLight, //!< lighten or darken, depending on source
kDifference, //!< subtract darker from lighter with higher contrast
kExclusion, //!< subtract darker from lighter with lower contrast
kMultiply, //!< multiply source with destination, darkening image
kLastSeparableMode = kMultiply, //!< last blend mode operating separately on components
kHue, //!< hue of source with saturation and luminosity of destination
kSaturation, //!< saturation of source with hue and luminosity of destination
kColor, //!< hue and saturation of source with luminosity of destination
kLuminosity, //!< luminosity of source with hue and saturation of destination
kLastMode = kLuminosity, //!< last valid value
};
/** Returns name of blendMode as null-terminated C string.
@param blendMode one of:
SkBlendMode::kClear, SkBlendMode::kSrc, SkBlendMode::kDst,
SkBlendMode::kSrcOver, SkBlendMode::kDstOver, SkBlendMode::kSrcIn,
SkBlendMode::kDstIn, SkBlendMode::kSrcOut, SkBlendMode::kDstOut,
SkBlendMode::kSrcATop, SkBlendMode::kDstATop, SkBlendMode::kXor,
SkBlendMode::kPlus, SkBlendMode::kModulate, SkBlendMode::kScreen,
SkBlendMode::kOverlay, SkBlendMode::kDarken, SkBlendMode::kLighten,
SkBlendMode::kColorDodge, SkBlendMode::kColorBurn, SkBlendMode::kHardLight,
SkBlendMode::kSoftLight, SkBlendMode::kDifference, SkBlendMode::kExclusion,
SkBlendMode::kMultiply, SkBlendMode::kHue, SkBlendMode::kSaturation,
SkBlendMode::kColor, SkBlendMode::kLuminosity
@return C string
*/
SK_API const char* SkBlendMode_Name(SkBlendMode blendMode);
#endif

22
skia/include/core/SkBlurTypes.h vendored Normal file
View File

@ -0,0 +1,22 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkBlurTypes_DEFINED
#define SkBlurTypes_DEFINED
#include "SkTypes.h"
enum SkBlurStyle : int {
kNormal_SkBlurStyle, //!< fuzzy inside and outside
kSolid_SkBlurStyle, //!< solid inside, fuzzy outside
kOuter_SkBlurStyle, //!< nothing inside, fuzzy outside
kInner_SkBlurStyle, //!< fuzzy inside, nothing outside
kLastEnum_SkBlurStyle = kInner_SkBlurStyle,
};
#endif

2779
skia/include/core/SkCanvas.h vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,93 @@
/*
* Copyright 2018 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkCanvasVirtualEnforcer_DEFINED
#define SkCanvasVirtualEnforcer_DEFINED
#include "SkCanvas.h"
// If you would ordinarily want to inherit from Base (eg SkCanvas, SkNWayCanvas), instead
// inherit from SkCanvasVirtualEnforcer<Base>, which will make the build fail if you forget
// to override one of SkCanvas' key virtual hooks.
template <typename Base>
class SkCanvasVirtualEnforcer : public Base {
public:
using Base::Base;
protected:
void onDrawPaint(const SkPaint& paint) override = 0;
void onDrawRect(const SkRect& rect, const SkPaint& paint) override = 0;
void onDrawRRect(const SkRRect& rrect, const SkPaint& paint) override = 0;
void onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
const SkPaint& paint) override = 0;
void onDrawOval(const SkRect& rect, const SkPaint& paint) override = 0;
void onDrawArc(const SkRect& rect, SkScalar startAngle, SkScalar sweepAngle, bool useCenter,
const SkPaint& paint) override = 0;
void onDrawPath(const SkPath& path, const SkPaint& paint) override = 0;
void onDrawRegion(const SkRegion& region, const SkPaint& paint) override = 0;
void onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
const SkPaint& paint) override = 0;
void onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[],
const SkPaint& paint) override = 0;
void onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[],
SkScalar constY, const SkPaint& paint) override = 0;
void onDrawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[],
const SkRect* cullRect, const SkPaint& paint) override = 0;
void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
const SkPaint& paint) override = 0;
void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
const SkPoint texCoords[4], SkBlendMode mode,
const SkPaint& paint) override = 0;
void onDrawPoints(SkCanvas::PointMode mode, size_t count, const SkPoint pts[],
const SkPaint& paint) override = 0;
void onDrawVerticesObject(const SkVertices*, const SkVertices::Bone bones[], int boneCount,
SkBlendMode, const SkPaint&) override = 0;
void onDrawImage(const SkImage* image, SkScalar dx, SkScalar dy,
const SkPaint* paint) override = 0;
void onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst,
const SkPaint* paint, SkCanvas::SrcRectConstraint constraint) override = 0;
void onDrawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst,
const SkPaint* paint) override = 0;
void onDrawImageLattice(const SkImage* image, const SkCanvas::Lattice& lattice,
const SkRect& dst, const SkPaint* paint) override = 0;
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
// This is under active development for Chrome and not used in Android. Hold off on adding
// implementations in Android's SkCanvas subclasses until this stabilizes.
void onDrawImageSet(const SkCanvas::ImageSetEntry[], int count, SkFilterQuality,
SkBlendMode) override {};
#else
void onDrawImageSet(const SkCanvas::ImageSetEntry[], int count, SkFilterQuality,
SkBlendMode) override = 0;
#endif
void onDrawBitmap(const SkBitmap& bitmap, SkScalar dx, SkScalar dy,
const SkPaint* paint) override = 0;
void onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst,
const SkPaint* paint,
SkCanvas::SrcRectConstraint constraint) override = 0;
void onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
const SkPaint* paint) override = 0;
void onDrawBitmapLattice(const SkBitmap& bitmap, const SkCanvas::Lattice& lattice,
const SkRect& dst, const SkPaint* paint) override = 0;
void onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect rect[],
const SkColor colors[], int count, SkBlendMode mode, const SkRect* cull,
const SkPaint* paint) override = 0;
void onDrawAnnotation(const SkRect& rect, const char key[], SkData* value) override = 0;
void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&) override = 0;
void onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) override = 0;
void onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
const SkPaint* paint) override = 0;
};
#endif

33
skia/include/core/SkClipOp.h vendored Normal file
View File

@ -0,0 +1,33 @@
/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkClipOp_DEFINED
#define SkClipOp_DEFINED
#include "SkTypes.h"
enum class SkClipOp {
kDifference = 0,
kIntersect = 1,
#ifdef SK_SUPPORT_DEPRECATED_CLIPOPS
kUnion_deprecated = 2,
kXOR_deprecated = 3,
kReverseDifference_deprecated = 4,
kReplace_deprecated = 5,
#else
kExtraEnumNeedInternallyPleaseIgnoreWillGoAway2 = 2,
kExtraEnumNeedInternallyPleaseIgnoreWillGoAway3 = 3,
kExtraEnumNeedInternallyPleaseIgnoreWillGoAway4 = 4,
kExtraEnumNeedInternallyPleaseIgnoreWillGoAway5 = 5,
#endif
// Used internally for validation, can only shrink to 1 when the deprecated flag is gone
kMax_EnumValue = 5,
};
#endif

389
skia/include/core/SkColor.h vendored Normal file
View File

@ -0,0 +1,389 @@
/*
* 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.
*/
/* Generated by tools/bookmaker from include/core/SkColor.h and docs/SkColor_Reference.bmh
on 2018-06-14 13:13:34. Additional documentation and examples can be found at:
https://skia.org/user/api/SkColor_Reference
You may edit either file directly. Structural changes to public interfaces require
editing both files. After editing docs/SkColor_Reference.bmh, run:
bookmaker -b docs -i include/core/SkColor.h -p
to create an updated version of this file.
*/
#ifndef SkColor_DEFINED
#define SkColor_DEFINED
#include "SkImageInfo.h"
#include "SkScalar.h"
#include "SkTypes.h"
/** \file SkColor.h
Types, consts, functions, and macros for colors.
*/
/** 8-bit type for an alpha value. 255 is 100% opaque, zero is 100% transparent.
*/
typedef uint8_t SkAlpha;
/** 32-bit ARGB color value, unpremultiplied. Color components are always in
a known order. This is different from SkPMColor, which has its bytes in a configuration
dependent order, to match the format of kBGRA_8888_SkColorType bitmaps. SkColor
is the type used to specify colors in SkPaint and in gradients.
Color that is premultiplied has the same component values as color
that is unpremultiplied if alpha is 255, fully opaque, although may have the
component values in a different order.
*/
typedef uint32_t SkColor;
/** Returns color value from 8-bit component values. Asserts if SK_DEBUG is defined
if a, r, g, or b exceed 255. Since color is unpremultiplied, a may be smaller
than the largest of r, g, and b.
@param a amount of alpha, from fully transparent (0) to fully opaque (255)
@param r amount of red, from no red (0) to full red (255)
@param g amount of green, from no green (0) to full green (255)
@param b amount of blue, from no blue (0) to full blue (255)
@return color and alpha, unpremultiplied
*/
static constexpr inline SkColor SkColorSetARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
return SkASSERT(a <= 255 && r <= 255 && g <= 255 && b <= 255),
(a << 24) | (r << 16) | (g << 8) | (b << 0);
}
/** Returns color value from 8-bit component values, with alpha set
fully opaque to 255.
*/
#define SkColorSetRGB(r, g, b) SkColorSetARGB(0xFF, r, g, b)
/** Returns alpha byte from color value.
*/
#define SkColorGetA(color) (((color) >> 24) & 0xFF)
/** Returns red component of color, from zero to 255.
*/
#define SkColorGetR(color) (((color) >> 16) & 0xFF)
/** Returns green component of color, from zero to 255.
*/
#define SkColorGetG(color) (((color) >> 8) & 0xFF)
/** Returns blue component of color, from zero to 255.
*/
#define SkColorGetB(color) (((color) >> 0) & 0xFF)
/** Returns unpremultiplied color with red, blue, and green set from c; and alpha set
from a. Alpha component of c is ignored and is replaced by a in result.
@param c packed RGB, eight bits per component
@param a alpha: transparent at zero, fully opaque at 255
@return color with transparency
*/
static constexpr inline SkColor SkColorSetA(SkColor c, U8CPU a) {
return (c & 0x00FFFFFF) | (a << 24);
}
/** Represents fully transparent SkAlpha value. SkAlpha ranges from zero,
fully transparent; to 255, fully opaque.
*/
constexpr SkAlpha SK_AlphaTRANSPARENT = 0x00;
/** Represents fully opaque SkAlpha value. SkAlpha ranges from zero,
fully transparent; to 255, fully opaque.
*/
constexpr SkAlpha SK_AlphaOPAQUE = 0xFF;
/** Represents fully transparent SkColor. May be used to initialize a destination
containing a mask or a non-rectangular image.
*/
constexpr SkColor SK_ColorTRANSPARENT = SkColorSetARGB(0x00, 0x00, 0x00, 0x00);
/** Represents fully opaque black.
*/
constexpr SkColor SK_ColorBLACK = SkColorSetARGB(0xFF, 0x00, 0x00, 0x00);
/** Represents fully opaque dark gray.
Note that SVG dark gray is equivalent to 0xFFA9A9A9.
*/
constexpr SkColor SK_ColorDKGRAY = SkColorSetARGB(0xFF, 0x44, 0x44, 0x44);
/** Represents fully opaque gray.
Note that HTML gray is equivalent to 0xFF808080.
*/
constexpr SkColor SK_ColorGRAY = SkColorSetARGB(0xFF, 0x88, 0x88, 0x88);
/** Represents fully opaque light gray. HTML silver is equivalent to 0xFFC0C0C0.
Note that SVG light gray is equivalent to 0xFFD3D3D3.
*/
constexpr SkColor SK_ColorLTGRAY = SkColorSetARGB(0xFF, 0xCC, 0xCC, 0xCC);
/** Represents fully opaque white.
*/
constexpr SkColor SK_ColorWHITE = SkColorSetARGB(0xFF, 0xFF, 0xFF, 0xFF);
/** Represents fully opaque red.
*/
constexpr SkColor SK_ColorRED = SkColorSetARGB(0xFF, 0xFF, 0x00, 0x00);
/** Represents fully opaque green. HTML lime is equivalent.
Note that HTML green is equivalent to 0xFF008000.
*/
constexpr SkColor SK_ColorGREEN = SkColorSetARGB(0xFF, 0x00, 0xFF, 0x00);
/** Represents fully opaque blue.
*/
constexpr SkColor SK_ColorBLUE = SkColorSetARGB(0xFF, 0x00, 0x00, 0xFF);
/** Represents fully opaque yellow.
*/
constexpr SkColor SK_ColorYELLOW = SkColorSetARGB(0xFF, 0xFF, 0xFF, 0x00);
/** Represents fully opaque cyan. HTML aqua is equivalent.
*/
constexpr SkColor SK_ColorCYAN = SkColorSetARGB(0xFF, 0x00, 0xFF, 0xFF);
/** Represents fully opaque magenta. HTML fuchsia is equivalent.
*/
constexpr SkColor SK_ColorMAGENTA = SkColorSetARGB(0xFF, 0xFF, 0x00, 0xFF);
/** Converts RGB to its HSV components.
hsv[0] contains hsv hue, a value from zero to less than 360.
hsv[1] contains hsv saturation, a value from zero to one.
hsv[2] contains hsv value, a value from zero to one.
@param red red component value from zero to 255
@param green green component value from zero to 255
@param blue blue component value from zero to 255
@param hsv three element array which holds the resulting HSV components
*/
SK_API void SkRGBToHSV(U8CPU red, U8CPU green, U8CPU blue, SkScalar hsv[3]);
/** Converts ARGB to its HSV components. Alpha in ARGB is ignored.
hsv[0] contains hsv hue, and is assigned a value from zero to less than 360.
hsv[1] contains hsv saturation, a value from zero to one.
hsv[2] contains hsv value, a value from zero to one.
@param color ARGB color to convert
@param hsv three element array which holds the resulting HSV components
*/
static inline void SkColorToHSV(SkColor color, SkScalar hsv[3]) {
SkRGBToHSV(SkColorGetR(color), SkColorGetG(color), SkColorGetB(color), hsv);
}
/** Converts HSV components to an ARGB color. Alpha is passed through unchanged.
hsv[0] represents hsv hue, an angle from zero to less than 360.
hsv[1] represents hsv saturation, and varies from zero to one.
hsv[2] represents hsv value, and varies from zero to one.
Out of range hsv values are pinned.
@param alpha alpha component of the returned ARGB color
@param hsv three element array which holds the input HSV components
@return ARGB equivalent to HSV
*/
SK_API SkColor SkHSVToColor(U8CPU alpha, const SkScalar hsv[3]);
/** Converts HSV components to an ARGB color. Alpha is set to 255.
hsv[0] represents hsv hue, an angle from zero to less than 360.
hsv[1] represents hsv saturation, and varies from zero to one.
hsv[2] represents hsv value, and varies from zero to one.
Out of range hsv values are pinned.
@param hsv three element array which holds the input HSV components
@return RGB equivalent to HSV
*/
static inline SkColor SkHSVToColor(const SkScalar hsv[3]) {
return SkHSVToColor(0xFF, hsv);
}
/** 32-bit ARGB color value, premultiplied. The byte order for this value is
configuration dependent, matching the format of kBGRA_8888_SkColorType bitmaps.
This is different from SkColor, which is unpremultiplied, and is always in the
same byte order.
*/
typedef uint32_t SkPMColor;
/** Returns a SkPMColor value from unpremultiplied 8-bit component values.
@param a amount of alpha, from fully transparent (0) to fully opaque (255)
@param r amount of red, from no red (0) to full red (255)
@param g amount of green, from no green (0) to full green (255)
@param b amount of blue, from no blue (0) to full blue (255)
@return premultiplied color
*/
SK_API SkPMColor SkPreMultiplyARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b);
/** Returns pmcolor closest to color c. Multiplies c RGB components by the c alpha,
and arranges the bytes to match the format of kN32_SkColorType.
@param c unpremultiplied ARGB color
@return premultiplied color
*/
SK_API SkPMColor SkPreMultiplyColor(SkColor c);
/** \struct SkRGBA4f
RGBA color value, holding four floating point components. Color components are always in
a known order. kAT determines if the SkRGBA4f's R, G, and B components are premultiplied
by alpha or not.
Skia's public API always uses unpremultiplied colors, which can be stored as
SkRGBA4f<kUnpremul_SkAlphaType>. For convenience, this type can also be referred to
as SkColor4f.
*/
template <SkAlphaType kAT>
struct SkRGBA4f {
float fR; //!< red component
float fG; //!< green component
float fB; //!< blue component
float fA; //!< alpha component
/** Compares SkRGBA4f with other, and returns true if all components are equal.
@param other SkRGBA4f to compare
@return true if SkRGBA4f equals other
*/
bool operator==(const SkRGBA4f& other) const {
return fA == other.fA && fR == other.fR && fG == other.fG && fB == other.fB;
}
/** Compares SkRGBA4f with other, and returns true if not all components are equal.
@param other SkRGBA4f to compare
@return true if SkRGBA4f is not equal to other
*/
bool operator!=(const SkRGBA4f& other) const {
return !(*this == other);
}
/** Returns SkRGBA4f multiplied by scale.
@param scale value to multiply by
@return SkRGBA4f as (fR * scale, fG * scale, fB * scale, fA * scale)
*/
SkRGBA4f operator*(float scale) const {
return { fR * scale, fG * scale, fB * scale, fA * scale };
}
/** Returns SkRGBA4f multiplied component-wise by scale.
@param scale SkRGBA4f to multiply by
@return SkRGBA4f as (fR * scale.fR, fG * scale.fG, fB * scale.fB, fA * scale.fA)
*/
SkRGBA4f operator*(const SkRGBA4f& scale) const {
return { fR * scale.fR, fG * scale.fG, fB * scale.fB, fA * scale.fA };
}
/** Returns a pointer to components of SkRGBA4f, for array access.
@return pointer to array [fR, fG, fB, fA]
*/
const float* vec() const { return &fR; }
/** Returns a pointer to components of SkRGBA4f, for array access.
@return pointer to array [fR, fG, fB, fA]
*/
float* vec() { return &fR; }
/** Returns one component. Asserts if index is out of range and SK_DEBUG is defined.
@param index one of: 0 (fR), 1 (fG), 2 (fB), 3 (fA)
@return value corresponding to index
*/
float operator[](int index) const {
SkASSERT(index >= 0 && index < 4);
return this->vec()[index];
}
/** Returns one component. Asserts if index is out of range and SK_DEBUG is defined.
@param index one of: 0 (fR), 1 (fG), 2 (fB), 3 (fA)
@return value corresponding to index
*/
float& operator[](int index) {
SkASSERT(index >= 0 && index < 4);
return this->vec()[index];
}
/** Returns true if SkRGBA4f is an opaque color. Asserts if fA is out of range and
SK_DEBUG is defined.
@return true if SkRGBA4f is opaque
*/
bool isOpaque() const {
SkASSERT(fA <= 1.0f && fA >= 0.0f);
return fA == 1.0f;
}
/** Returns closest SkRGBA4f to SkColor. Only allowed if SkRGBA4f is unpremultiplied.
@return SkColor as SkRGBA4f
*/
static SkRGBA4f FromColor(SkColor); // impl. depends on kAT
/** Returns closest SkColor to SkRGBA4f. Only allowed if SkRGBA4f is unpremultiplied.
@return color as SkColor
*/
SkColor toSkColor() const; // impl. depends on kAT
/** Returns closest SkRGBA4f to SkPMColor. Only allowed if SkRGBA4f is premultiplied.
@return SkPMColor as SkRGBA4f
*/
static SkRGBA4f FromPMColor(SkPMColor); // impl. depends on kAT
/** Returns SkRGBA4f premultiplied by alpha. Asserts at compile time if SkRGBA4f is
already premultiplied.
@return premultiplied color
*/
SkRGBA4f<kPremul_SkAlphaType> premul() const {
static_assert(kAT == kUnpremul_SkAlphaType, "");
return { fR * fA, fG * fA, fB * fA, fA };
}
/** Returns SkRGBA4f unpremultiplied by alpha. Asserts at compile time if SkRGBA4f is
already unpremultiplied.
@return unpremultiplied color
*/
SkRGBA4f<kUnpremul_SkAlphaType> unpremul() const {
static_assert(kAT == kPremul_SkAlphaType, "");
if (fA == 0.0f) {
return { 0, 0, 0, 0 };
} else {
float invAlpha = 1 / fA;
return { fR * invAlpha, fG * invAlpha, fB * invAlpha, fA };
}
}
// This produces bytes in RGBA order (eg GrColor). Impl. is the same, regardless of kAT
uint32_t toBytes_RGBA() const;
static SkRGBA4f FromBytes_RGBA(uint32_t color);
SkRGBA4f makeOpaque() const {
return { fR, fG, fB, 1.0f };
}
};
/** \struct SkColor4f
RGBA color value, holding four floating point components. Color components are always in
a known order, and are unpremultiplied.
This is a specialization of SkRGBA4f. For details, @see SkRGBA4f.
*/
using SkColor4f = SkRGBA4f<kUnpremul_SkAlphaType>;
template <> SK_API SkColor4f SkColor4f::FromColor(SkColor);
template <> SK_API SkColor SkColor4f::toSkColor() const;
#endif

196
skia/include/core/SkColorFilter.h vendored Normal file
View File

@ -0,0 +1,196 @@
/*
* Copyright 2006 The Android Open Source Project
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkColorFilter_DEFINED
#define SkColorFilter_DEFINED
#include "SkBlendMode.h"
#include "SkColor.h"
#include "SkFlattenable.h"
#include "SkRefCnt.h"
class GrContext;
class GrColorSpaceInfo;
class GrFragmentProcessor;
class SkArenaAlloc;
class SkBitmap;
class SkColorSpace;
class SkColorSpaceXformer;
class SkRasterPipeline;
class SkString;
/**
* ColorFilters are optional objects in the drawing pipeline. When present in
* a paint, they are called with the "src" colors, and return new colors, which
* are then passed onto the next stage (either ImageFilter or Xfermode).
*
* All subclasses are required to be reentrant-safe : it must be legal to share
* the same instance between several threads.
*/
class SK_API SkColorFilter : public SkFlattenable {
public:
/**
* If the filter can be represented by a source color plus Mode, this
* returns true, and sets (if not NULL) the color and mode appropriately.
* If not, this returns false and ignores the parameters.
*/
virtual bool asColorMode(SkColor* color, SkBlendMode* bmode) const;
/**
* If the filter can be represented by a 5x4 matrix, this
* returns true, and sets the matrix appropriately.
* If not, this returns false and ignores the parameter.
*/
virtual bool asColorMatrix(SkScalar matrix[20]) const;
/**
* If the filter can be represented by per-component table, return true,
* and if table is not null, copy the bitmap containing the table into it.
*
* The table bitmap will be in SkBitmap::kA8_Config. Each row corresponding
* to each component in ARGB order. e.g. row[0] == alpha, row[1] == red,
* etc. To transform a color, you (logically) perform the following:
*
* a' = *table.getAddr8(a, 0);
* r' = *table.getAddr8(r, 1);
* g' = *table.getAddr8(g, 2);
* b' = *table.getAddr8(b, 3);
*
* The original component value is the horizontal index for a given row,
* and the stored value at that index is the new value for that component.
*/
virtual bool asComponentTable(SkBitmap* table) const;
void appendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*, bool shaderIsOpaque) const;
enum Flags {
/** If set the filter methods will not change the alpha channel of the colors.
*/
kAlphaUnchanged_Flag = 1 << 0,
};
/** Returns the flags for this filter. Override in subclasses to return custom flags.
*/
virtual uint32_t getFlags() const { return 0; }
SkColor filterColor(SkColor) const;
SkColor4f filterColor4f(const SkColor4f&, SkColorSpace*) const;
/** Create a colorfilter that uses the specified color and mode.
If the Mode is DST, this function will return NULL (since that
mode will have no effect on the result).
@param c The source color used with the specified mode
@param mode The blend that is applied to each color in
the colorfilter's filterSpan[16,32] methods
@return colorfilter object that applies the src color and mode,
or NULL if the mode will have no effect.
*/
static sk_sp<SkColorFilter> MakeModeFilter(SkColor c, SkBlendMode mode);
/** Construct a colorfilter whose effect is to first apply the inner filter and then apply
* this filter, applied to the output of the inner filter.
*
* result = this(inner(...))
*
* Due to internal limits, it is possible that this will return NULL, so the caller must
* always check.
*/
sk_sp<SkColorFilter> makeComposed(sk_sp<SkColorFilter> inner) const;
// DEPRECATED, call makeComposed instead
static sk_sp<SkColorFilter> MakeComposeFilter(sk_sp<SkColorFilter> outer,
sk_sp<SkColorFilter> inner) {
return outer ? outer->makeComposed(inner) : inner;
}
/** Construct a color filter that transforms a color by a 4x5 matrix. The matrix is in row-
* major order and the translation column is specified in unnormalized, 0...255, space.
*/
static sk_sp<SkColorFilter> MakeMatrixFilterRowMajor255(const SkScalar array[20]);
/** Construct a colorfilter that applies the srgb gamma curve to the RGB channels */
static sk_sp<SkColorFilter> MakeLinearToSRGBGamma();
/** Construct a colorfilter that applies the inverse of the srgb gamma curve to the
* RGB channels
*/
static sk_sp<SkColorFilter> MakeSRGBToLinearGamma();
#if SK_SUPPORT_GPU
/**
* A subclass may implement this factory function to work with the GPU backend. It returns
* a GrFragmentProcessor that implemets the color filter in GPU shader code.
*
* The fragment processor receives a premultiplied input color and produces a premultiplied
* output color.
*
* A null return indicates that the color filter isn't implemented for the GPU backend.
*/
virtual std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(
GrContext*, const GrColorSpaceInfo& dstColorSpaceInfo) const;
#endif
bool affectsTransparentBlack() const {
return this->filterColor(SK_ColorTRANSPARENT) != SK_ColorTRANSPARENT;
}
static void RegisterFlattenables();
static SkFlattenable::Type GetFlattenableType() {
return kSkColorFilter_Type;
}
SkFlattenable::Type getFlattenableType() const override {
return kSkColorFilter_Type;
}
static sk_sp<SkColorFilter> Deserialize(const void* data, size_t size,
const SkDeserialProcs* procs = nullptr) {
return sk_sp<SkColorFilter>(static_cast<SkColorFilter*>(
SkFlattenable::Deserialize(
kSkColorFilter_Type, data, size, procs).release()));
}
protected:
SkColorFilter() {}
sk_sp<SkColorFilter> makeColorSpace(SkColorSpaceXformer* xformer) const {
return this->onMakeColorSpace(xformer);
}
virtual sk_sp<SkColorFilter> onMakeColorSpace(SkColorSpaceXformer*) const {
return sk_ref_sp(const_cast<SkColorFilter*>(this));
}
/**
* If this subclass can optimally createa composition with the inner filter, return it as
* a new filter (which the caller must unref() when it is done). If no such optimization
* is known, return NULL.
*
* e.g. result(color) == this_filter(inner(color))
*/
virtual sk_sp<SkColorFilter> onMakeComposed(sk_sp<SkColorFilter>) const { return nullptr; }
private:
/*
* Returns 1 if this is a single filter (not a composition of other filters), otherwise it
* reutrns the number of leaf-node filters in a composition. This should be the same value
* as the number of GrFragmentProcessors returned by asFragmentProcessors's array parameter.
*
* e.g. compose(filter, compose(compose(filter, filter), filter)) --> 4
*/
virtual int privateComposedFilterCount() const { return 1; }
virtual void onAppendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*,
bool shaderIsOpaque) const = 0;
friend class SkColorSpaceXformer;
friend class SkComposeColorFilter;
typedef SkFlattenable INHERITED;
};
#endif

163
skia/include/core/SkColorPriv.h vendored Normal file
View File

@ -0,0 +1,163 @@
/*
* 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 SkColorPriv_DEFINED
#define SkColorPriv_DEFINED
#include "../private/SkTo.h"
#include "SkColor.h"
#include "SkMath.h"
/** Turn 0..255 into 0..256 by adding 1 at the half-way point. Used to turn a
byte into a scale value, so that we can say scale * value >> 8 instead of
alpha * value / 255.
In debugging, asserts that alpha is 0..255
*/
static inline unsigned SkAlpha255To256(U8CPU alpha) {
SkASSERT(SkToU8(alpha) == alpha);
// this one assues that blending on top of an opaque dst keeps it that way
// even though it is less accurate than a+(a>>7) for non-opaque dsts
return alpha + 1;
}
/** Multiplify value by 0..256, and shift the result down 8
(i.e. return (value * alpha256) >> 8)
*/
#define SkAlphaMul(value, alpha256) (((value) * (alpha256)) >> 8)
static inline U8CPU SkUnitScalarClampToByte(SkScalar x) {
return static_cast<U8CPU>(SkScalarPin(x, 0, 1) * 255 + 0.5);
}
#define SK_A32_BITS 8
#define SK_R32_BITS 8
#define SK_G32_BITS 8
#define SK_B32_BITS 8
#define SK_A32_MASK ((1 << SK_A32_BITS) - 1)
#define SK_R32_MASK ((1 << SK_R32_BITS) - 1)
#define SK_G32_MASK ((1 << SK_G32_BITS) - 1)
#define SK_B32_MASK ((1 << SK_B32_BITS) - 1)
/*
* Skia's 32bit backend only supports 1 swizzle order at a time (compile-time).
* This is specified by 4 defines SK_A32_SHIFT, SK_R32_SHIFT, ... for G and B.
*
* For easier compatibility with Skia's GPU backend, we further restrict these
* to either (in memory-byte-order) RGBA or BGRA. Note that this "order" does
* not directly correspond to the same shift-order, since we have to take endianess
* into account.
*
* Here we enforce this constraint.
*/
#ifdef SK_CPU_BENDIAN
#define SK_RGBA_R32_SHIFT 24
#define SK_RGBA_G32_SHIFT 16
#define SK_RGBA_B32_SHIFT 8
#define SK_RGBA_A32_SHIFT 0
#define SK_BGRA_B32_SHIFT 24
#define SK_BGRA_G32_SHIFT 16
#define SK_BGRA_R32_SHIFT 8
#define SK_BGRA_A32_SHIFT 0
#else
#define SK_RGBA_R32_SHIFT 0
#define SK_RGBA_G32_SHIFT 8
#define SK_RGBA_B32_SHIFT 16
#define SK_RGBA_A32_SHIFT 24
#define SK_BGRA_B32_SHIFT 0
#define SK_BGRA_G32_SHIFT 8
#define SK_BGRA_R32_SHIFT 16
#define SK_BGRA_A32_SHIFT 24
#endif
#if defined(SK_PMCOLOR_IS_RGBA) || defined(SK_PMCOLOR_IS_BGRA)
#error "Configure PMCOLOR by setting SK_R32_SHIFT, etc"
#endif
// Deduce which SK_PMCOLOR_IS_ to define from the _SHIFT defines
#if (SK_A32_SHIFT == SK_RGBA_A32_SHIFT && \
SK_R32_SHIFT == SK_RGBA_R32_SHIFT && \
SK_G32_SHIFT == SK_RGBA_G32_SHIFT && \
SK_B32_SHIFT == SK_RGBA_B32_SHIFT)
#define SK_PMCOLOR_IS_RGBA
#elif (SK_A32_SHIFT == SK_BGRA_A32_SHIFT && \
SK_R32_SHIFT == SK_BGRA_R32_SHIFT && \
SK_G32_SHIFT == SK_BGRA_G32_SHIFT && \
SK_B32_SHIFT == SK_BGRA_B32_SHIFT)
#define SK_PMCOLOR_IS_BGRA
#else
#error "need 32bit packing to be either RGBA or BGRA"
#endif
#define SkGetPackedA32(packed) ((uint32_t)((packed) << (24 - SK_A32_SHIFT)) >> 24)
#define SkGetPackedR32(packed) ((uint32_t)((packed) << (24 - SK_R32_SHIFT)) >> 24)
#define SkGetPackedG32(packed) ((uint32_t)((packed) << (24 - SK_G32_SHIFT)) >> 24)
#define SkGetPackedB32(packed) ((uint32_t)((packed) << (24 - SK_B32_SHIFT)) >> 24)
#define SkA32Assert(a) SkASSERT((unsigned)(a) <= SK_A32_MASK)
#define SkR32Assert(r) SkASSERT((unsigned)(r) <= SK_R32_MASK)
#define SkG32Assert(g) SkASSERT((unsigned)(g) <= SK_G32_MASK)
#define SkB32Assert(b) SkASSERT((unsigned)(b) <= SK_B32_MASK)
/**
* Pack the components into a SkPMColor, checking (in the debug version) that
* the components are 0..255, and are already premultiplied (i.e. alpha >= color)
*/
static inline SkPMColor SkPackARGB32(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
SkA32Assert(a);
SkASSERT(r <= a);
SkASSERT(g <= a);
SkASSERT(b <= a);
return (a << SK_A32_SHIFT) | (r << SK_R32_SHIFT) |
(g << SK_G32_SHIFT) | (b << SK_B32_SHIFT);
}
/**
* Same as SkPackARGB32, but this version guarantees to not check that the
* values are premultiplied in the debug version.
*/
static inline SkPMColor SkPackARGB32NoCheck(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
return (a << SK_A32_SHIFT) | (r << SK_R32_SHIFT) |
(g << SK_G32_SHIFT) | (b << SK_B32_SHIFT);
}
static inline
SkPMColor SkPremultiplyARGBInline(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
SkA32Assert(a);
SkR32Assert(r);
SkG32Assert(g);
SkB32Assert(b);
if (a != 255) {
r = SkMulDiv255Round(r, a);
g = SkMulDiv255Round(g, a);
b = SkMulDiv255Round(b, a);
}
return SkPackARGB32(a, r, g, b);
}
// When Android is compiled optimizing for size, SkAlphaMulQ doesn't get
// inlined; forcing inlining significantly improves performance.
static SK_ALWAYS_INLINE uint32_t SkAlphaMulQ(uint32_t c, unsigned scale) {
uint32_t mask = 0xFF00FF;
uint32_t rb = ((c & mask) * scale) >> 8;
uint32_t ag = ((c >> 8) & mask) * scale;
return (rb & mask) | (ag & ~mask);
}
static inline SkPMColor SkPMSrcOver(SkPMColor src, SkPMColor dst) {
return src + SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src)));
}
#endif

237
skia/include/core/SkColorSpace.h vendored Normal file
View File

@ -0,0 +1,237 @@
/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkColorSpace_DEFINED
#define SkColorSpace_DEFINED
#include "../private/SkOnce.h"
#include "SkMatrix44.h"
#include "SkRefCnt.h"
#include <memory>
class SkData;
struct skcms_ICCProfile;
enum SkGammaNamed {
kLinear_SkGammaNamed,
kSRGB_SkGammaNamed,
k2Dot2Curve_SkGammaNamed,
kNonStandard_SkGammaNamed,
};
/**
* Describes a color gamut with primaries and a white point.
*/
struct SK_API SkColorSpacePrimaries {
float fRX;
float fRY;
float fGX;
float fGY;
float fBX;
float fBY;
float fWX;
float fWY;
/**
* Convert primaries and a white point to a toXYZD50 matrix, the preferred color gamut
* representation of SkColorSpace.
*/
bool toXYZD50(SkMatrix44* toXYZD50) const;
};
/**
* Contains the coefficients for a common transfer function equation, specified as
* a transformation from a curved space to linear.
*
* LinearVal = sign(InputVal) * ( C*|InputVal| + F ), for 0.0f <= |InputVal| < D
* LinearVal = sign(InputVal) * ( (A*|InputVal| + B)^G + E), for D <= |InputVal|
*
* Function must be positive and increasing.
*/
struct SK_API SkColorSpaceTransferFn {
float fG;
float fA;
float fB;
float fC;
float fD;
float fE;
float fF;
};
class SK_API SkColorSpace : public SkNVRefCnt<SkColorSpace> {
public:
/**
* Create the sRGB color space.
*/
static sk_sp<SkColorSpace> MakeSRGB();
/**
* Colorspace with the sRGB primaries, but a linear (1.0) gamma. Commonly used for
* half-float surfaces, and high precision individual colors (gradient stops, etc...)
*/
static sk_sp<SkColorSpace> MakeSRGBLinear();
enum RenderTargetGamma : uint8_t {
kLinear_RenderTargetGamma,
/**
* Transfer function is the canonical sRGB curve, which has a short linear segment
* followed by a 2.4f exponential.
*/
kSRGB_RenderTargetGamma,
};
enum Gamut {
kSRGB_Gamut,
kAdobeRGB_Gamut,
kDCIP3_D65_Gamut,
kRec2020_Gamut,
};
/**
* Create an SkColorSpace from a transfer function and a color gamut.
*
* Transfer function can be specified as an enum or as the coefficients to an equation.
* Gamut can be specified as an enum or as the matrix transformation to XYZ D50.
*/
static sk_sp<SkColorSpace> MakeRGB(RenderTargetGamma gamma, Gamut gamut);
static sk_sp<SkColorSpace> MakeRGB(RenderTargetGamma gamma, const SkMatrix44& toXYZD50);
static sk_sp<SkColorSpace> MakeRGB(const SkColorSpaceTransferFn& coeffs, Gamut gamut);
static sk_sp<SkColorSpace> MakeRGB(const SkColorSpaceTransferFn& coeffs,
const SkMatrix44& toXYZD50);
static sk_sp<SkColorSpace> MakeRGB(SkGammaNamed gammaNamed, const SkMatrix44& toXYZD50);
/**
* Create an SkColorSpace from a parsed (skcms) ICC profile.
*/
static sk_sp<SkColorSpace> Make(const skcms_ICCProfile&);
/**
* Convert this color space to an skcms ICC profile struct.
*/
void toProfile(skcms_ICCProfile*) const;
SkGammaNamed gammaNamed() const { return fGammaNamed; }
/**
* Returns true if the color space gamma is near enough to be approximated as sRGB.
*/
bool gammaCloseToSRGB() const { return kSRGB_SkGammaNamed == fGammaNamed; }
/**
* Returns true if the color space gamma is linear.
*/
bool gammaIsLinear() const { return kLinear_SkGammaNamed == fGammaNamed; }
/**
* If the transfer function can be represented as coefficients to the standard
* equation, returns true and sets |fn| to the proper values.
*
* If not, returns false.
*/
bool isNumericalTransferFn(SkColorSpaceTransferFn* fn) const;
/**
* Returns true and sets |toXYZD50| if the color gamut can be described as a matrix.
* Returns false otherwise.
*/
bool toXYZD50(SkMatrix44* toXYZD50) const;
/**
* Returns a hash of the gamut transformation to XYZ D50. Allows for fast equality checking
* of gamuts, at the (very small) risk of collision.
*/
uint32_t toXYZD50Hash() const { return fToXYZD50Hash; }
/**
* Returns a color space with the same gamut as this one, but with a linear gamma.
* For color spaces whose gamut can not be described in terms of XYZ D50, returns
* linear sRGB.
*/
sk_sp<SkColorSpace> makeLinearGamma() const;
/**
* Returns a color space with the same gamut as this one, with with the sRGB transfer
* function. For color spaces whose gamut can not be described in terms of XYZ D50, returns
* sRGB.
*/
sk_sp<SkColorSpace> makeSRGBGamma() const;
/**
* Returns a color space with the same transfer function as this one, but with the primary
* colors rotated. For any XYZ space, this produces a new color space that maps RGB to GBR
* (when applied to a source), and maps RGB to BRG (when applied to a destination). For other
* types of color spaces, returns nullptr.
*
* This is used for testing, to construct color spaces that have severe and testable behavior.
*/
sk_sp<SkColorSpace> makeColorSpin() const;
/**
* Returns true if the color space is sRGB.
* Returns false otherwise.
*
* This allows a little bit of tolerance, given that we might see small numerical error
* in some cases: converting ICC fixed point to float, converting white point to D50,
* rounding decisions on transfer function and matrix.
*
* This does not consider a 2.2f exponential transfer function to be sRGB. While these
* functions are similar (and it is sometimes useful to consider them together), this
* function checks for logical equality.
*/
bool isSRGB() const;
/**
* Returns nullptr on failure. Fails when we fallback to serializing ICC data and
* the data is too large to serialize.
*/
sk_sp<SkData> serialize() const;
/**
* If |memory| is nullptr, returns the size required to serialize.
* Otherwise, serializes into |memory| and returns the size.
*/
size_t writeToMemory(void* memory) const;
static sk_sp<SkColorSpace> Deserialize(const void* data, size_t length);
/**
* If both are null, we return true. If one is null and the other is not, we return false.
* If both are non-null, we do a deeper compare.
*/
static bool Equals(const SkColorSpace*, const SkColorSpace*);
void transferFn(float gabcdef[7]) const;
void invTransferFn(float gabcdef[7]) const;
void gamutTransformTo(const SkColorSpace* dst, float src_to_dst_row_major[9]) const;
uint32_t transferFnHash() const { return fTransferFnHash; }
uint64_t hash() const { return (uint64_t)fTransferFnHash << 32 | fToXYZD50Hash; }
private:
friend class SkColorSpaceSingletonFactory;
SkColorSpace(SkGammaNamed gammaNamed,
const float transferFn[7],
const SkMatrix44& toXYZ);
void computeLazyDstFields() const;
SkGammaNamed fGammaNamed; // TODO: 2-bit, pack tightly? drop?
uint32_t fTransferFnHash;
uint32_t fToXYZD50Hash;
float fTransferFn[7];
float fToXYZD50_3x3[9]; // row-major
mutable float fInvTransferFn[7];
mutable float fFromXYZD50_3x3[9]; // row-major
mutable SkOnce fLazyDstFieldsOnce;
};
#endif

View File

@ -0,0 +1,20 @@
/*
* Copyright 2017 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkColorSpaceXformCanvas_DEFINED
#define SkColorSpaceXformCanvas_DEFINED
#include <SkCanvas.h>
#include <SkColorSpace.h>
#include <memory>
// Proxy SkCanvas calls to unowned target, transforming colors into targetCS as it goes.
// May return nullptr if |targetCS| is unsupported.
std::unique_ptr<SkCanvas> SK_API SkCreateColorSpaceXformCanvas(SkCanvas* target,
sk_sp<SkColorSpace> targetCS);
#endif //SkColorSpaceXformCanvas_DEFINED

30
skia/include/core/SkCoverageMode.h vendored Normal file
View File

@ -0,0 +1,30 @@
/*
* Copyright 2018 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkCoverageMode_DEFINED
#define SkCoverageMode_DEFINED
#include "SkTypes.h"
/**
* Describes geometric operations (ala SkRegion::Op) that can be applied to coverage bytes.
* These can be thought of as variants of porter-duff (SkBlendMode) modes, but only applied
* to the alpha channel.
*
* See SkMaskFilter for ways to use these when combining two different masks.
*/
enum class SkCoverageMode {
kUnion, // A B A+B-A*B
kIntersect, // A ∩ B A*B
kDifference, // A - B A*(1-B)
kReverseDifference, // B - A B*(1-A)
kXor, // A ⊕ B A+B-2*A*B
kLast = kXor,
};
#endif

182
skia/include/core/SkData.h vendored Normal file
View File

@ -0,0 +1,182 @@
/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkData_DEFINED
#define SkData_DEFINED
#include <stdio.h>
#include "SkRefCnt.h"
class SkStream;
/**
* 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 final : public SkNVRefCnt<SkData> {
public:
/**
* Returns the number of bytes stored.
*/
size_t size() const { return fSize; }
bool isEmpty() const { return 0 == fSize; }
/**
* Returns the ptr to the data.
*/
const void* data() const { return fPtr; }
/**
* Like data(), returns a read-only ptr into the data, but in this case
* it is cast to uint8_t*, to make it easy to add an offset to it.
*/
const uint8_t* bytes() const {
return reinterpret_cast<const uint8_t*>(fPtr);
}
/**
* USE WITH CAUTION.
* This call will assert that the refcnt is 1, as a precaution against modifying the
* contents when another client/thread has access to the data.
*/
void* writable_data() {
if (fSize) {
// only assert we're unique if we're not empty
SkASSERT(this->unique());
}
return fPtr;
}
/**
* Helper to copy a range of the data into a caller-provided buffer.
* Returns the actual number of bytes copied, after clamping offset and
* length to the size of the data. If buffer is NULL, it is ignored, and
* only the computed number of bytes is returned.
*/
size_t copyRange(size_t offset, size_t length, void* buffer) const;
/**
* Returns true if these two objects have the same length and contents,
* effectively returning 0 == memcmp(...)
*/
bool equals(const SkData* other) const;
/**
* Function that, if provided, will be called when the SkData goes out
* of scope, allowing for custom allocation/freeing of the data's contents.
*/
typedef void (*ReleaseProc)(const void* ptr, void* context);
/**
* Create a new dataref by copying the specified data
*/
static sk_sp<SkData> MakeWithCopy(const void* data, size_t length);
/**
* Create a new data with uninitialized contents. The caller should call writable_data()
* to write into the buffer, but this must be done before another ref() is made.
*/
static sk_sp<SkData> MakeUninitialized(size_t length);
/**
* Create a new dataref by copying the specified c-string
* (a null-terminated array of bytes). The returned SkData will have size()
* equal to strlen(cstr) + 1. If cstr is NULL, it will be treated the same
* as "".
*/
static sk_sp<SkData> MakeWithCString(const char cstr[]);
/**
* Create a new dataref, taking the ptr as is, and using the
* releaseproc to free it. The proc may be NULL.
*/
static sk_sp<SkData> MakeWithProc(const void* ptr, size_t length, ReleaseProc proc, void* ctx);
/**
* Call this when the data parameter is already const and will outlive the lifetime of the
* SkData. Suitable for with const globals.
*/
static sk_sp<SkData> MakeWithoutCopy(const void* data, size_t length) {
return MakeWithProc(data, length, DummyReleaseProc, nullptr);
}
/**
* Create a new dataref from a pointer allocated by malloc. The Data object
* takes ownership of that allocation, and will handling calling sk_free.
*/
static sk_sp<SkData> MakeFromMalloc(const void* data, size_t length);
/**
* Create a new dataref the file with the specified path.
* If the file cannot be opened, this returns NULL.
*/
static sk_sp<SkData> MakeFromFileName(const char path[]);
/**
* Create a new dataref from a stdio FILE.
* This does not take ownership of the FILE, nor close it.
* The caller is free to close the FILE at its convenience.
* The FILE must be open for reading only.
* Returns NULL on failure.
*/
static sk_sp<SkData> MakeFromFILE(FILE* f);
/**
* Create a new dataref from a file descriptor.
* This does not take ownership of the file descriptor, nor close it.
* The caller is free to close the file descriptor at its convenience.
* The file descriptor must be open for reading only.
* Returns NULL on failure.
*/
static sk_sp<SkData> MakeFromFD(int fd);
/**
* Attempt to read size bytes into a SkData. If the read succeeds, return the data,
* else return NULL. Either way the stream's cursor may have been changed as a result
* of calling read().
*/
static sk_sp<SkData> MakeFromStream(SkStream*, size_t size);
/**
* Create a new dataref using a subset of the data in the specified
* src dataref.
*/
static sk_sp<SkData> MakeSubset(const SkData* src, size_t offset, size_t length);
/**
* Returns a new empty dataref (or a reference to a shared empty dataref).
* New or shared, the caller must see that unref() is eventually called.
*/
static sk_sp<SkData> MakeEmpty();
private:
friend class SkNVRefCnt<SkData>;
ReleaseProc fReleaseProc;
void* fReleaseProcContext;
void* fPtr;
size_t fSize;
SkData(const void* ptr, size_t size, ReleaseProc, void* context);
explicit SkData(size_t size); // inplace new/delete
~SkData();
// Ensure the unsized delete is called.
void operator delete(void* p);
// shared internal factory
static sk_sp<SkData> PrivateNewWithCopy(const void* srcOrNull, size_t length);
static void DummyReleaseProc(const void*, void*); // {}
typedef SkRefCnt INHERITED;
};
#endif

119
skia/include/core/SkDataTable.h vendored Normal file
View File

@ -0,0 +1,119 @@
/*
* Copyright 2013 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkDataTable_DEFINED
#define SkDataTable_DEFINED
#include "../private/SkTDArray.h"
#include "SkData.h"
#include "SkString.h"
/**
* Like SkData, SkDataTable holds an immutable data buffer. The data buffer is
* organized into a table of entries, each with a length, so the entries are
* not required to all be the same size.
*/
class SK_API SkDataTable : public SkRefCnt {
public:
/**
* Returns true if the table is empty (i.e. has no entries).
*/
bool isEmpty() const { return 0 == fCount; }
/**
* Return the number of entries in the table. 0 for an empty table
*/
int count() const { return fCount; }
/**
* Return the size of the index'th entry in the table. The caller must
* ensure that index is valid for this table.
*/
size_t atSize(int index) const;
/**
* Return a pointer to the data of the index'th entry in the table.
* The caller must ensure that index is valid for this table.
*
* @param size If non-null, this returns the byte size of this entry. This
* will be the same value that atSize(index) would return.
*/
const void* at(int index, size_t* size = nullptr) const;
template <typename T>
const T* atT(int index, size_t* size = nullptr) const {
return reinterpret_cast<const T*>(this->at(index, size));
}
/**
* Returns the index'th entry as a c-string, and assumes that the trailing
* null byte had been copied into the table as well.
*/
const char* atStr(int index) const {
size_t size;
const char* str = this->atT<const char>(index, &size);
SkASSERT(strlen(str) + 1 == size);
return str;
}
typedef void (*FreeProc)(void* context);
static sk_sp<SkDataTable> MakeEmpty();
/**
* Return a new DataTable that contains a copy of the data stored in each
* "array".
*
* @param ptrs array of points to each element to be copied into the table.
* @param sizes array of byte-lengths for each entry in the corresponding
* ptrs[] array.
* @param count the number of array elements in ptrs[] and sizes[] to copy.
*/
static sk_sp<SkDataTable> MakeCopyArrays(const void * const * ptrs,
const size_t sizes[], int count);
/**
* Return a new table that contains a copy of the data in array.
*
* @param array contiguous array of data for all elements to be copied.
* @param elemSize byte-length for a given element.
* @param count the number of entries to be copied out of array. The number
* of bytes that will be copied is count * elemSize.
*/
static sk_sp<SkDataTable> MakeCopyArray(const void* array, size_t elemSize, int count);
static sk_sp<SkDataTable> MakeArrayProc(const void* array, size_t elemSize, int count,
FreeProc proc, void* context);
private:
struct Dir {
const void* fPtr;
uintptr_t fSize;
};
int fCount;
size_t fElemSize;
union {
const Dir* fDir;
const char* fElems;
} fU;
FreeProc fFreeProc;
void* fFreeProcContext;
SkDataTable();
SkDataTable(const void* array, size_t elemSize, int count,
FreeProc, void* context);
SkDataTable(const Dir*, int count, FreeProc, void* context);
virtual ~SkDataTable();
friend class SkDataTableBuilder; // access to Dir
typedef SkRefCnt INHERITED;
};
#endif

View File

@ -0,0 +1,165 @@
/*
* Copyright 2017 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkDeferredDisplayListMaker_DEFINED
#define SkDeferredDisplayListMaker_DEFINED
#include "SkImageInfo.h"
#include "SkRefCnt.h"
#include "SkSurfaceCharacterization.h"
#include "SkTypes.h"
#include "../private/SkDeferredDisplayList.h"
class GrBackendFormat;
class GrBackendTexture;
class GrContext;
class SkCanvas;
class SkImage;
class SkSurface;
struct SkYUVAIndex;
struct SkYUVASizeInfo;
/*
* This class is intended to be used as:
* Get an SkSurfaceCharacterization representing the intended gpu-backed destination SkSurface
* Create one of these (an SkDDLMaker) on the stack
* Get the canvas and render into it
* Snap off and hold on to an SkDeferredDisplayList
* Once your app actually needs the pixels, call SkSurface::draw(SkDeferredDisplayList*)
*
* This class never accesses the GPU but performs all the cpu work it can. It
* is thread-safe (i.e., one can break a scene into tiles and perform their cpu-side
* work in parallel ahead of time).
*/
class SK_API SkDeferredDisplayListRecorder {
public:
SkDeferredDisplayListRecorder(const SkSurfaceCharacterization&);
~SkDeferredDisplayListRecorder();
const SkSurfaceCharacterization& characterization() const {
return fCharacterization;
}
// The backing canvas will become invalid (and this entry point will return
// null) once 'detach' is called.
// Note: ownership of the SkCanvas is not transfered via this call.
SkCanvas* getCanvas();
std::unique_ptr<SkDeferredDisplayList> detach();
// Matches the defines in SkImage_GpuBase.h
typedef void* TextureContext;
typedef void (*TextureReleaseProc)(TextureContext textureContext);
typedef void (*TextureFulfillProc)(TextureContext textureContext, GrBackendTexture* outTexture);
typedef void (*PromiseDoneProc)(TextureContext textureContext);
/**
Create a new SkImage that is very similar to an SkImage created by MakeFromTexture. The main
difference is that the client doesn't have the backend texture on the gpu yet but they know
all the properties of the texture. So instead of passing in a GrBackendTexture the client
supplies a GrBackendFormat, width, height, and GrMipMapped state.
When we actually send the draw calls to the GPU, we will call the textureFulfillProc and
the client will return a GrBackendTexture to us. The properties of the GrBackendTexture must
match those set during the SkImage creation, and it must have a valid backend gpu texture.
The gpu texture supplied by the client must stay valid until we call the textureReleaseProc.
When we are done with the texture returned by the textureFulfillProc we will call the
textureReleaseProc passing in the textureContext. This is a signal to the client that they
are free to delete the underlying gpu texture. If future draws also use the same promise
image we will call the textureFulfillProc again if we've already called the
textureReleaseProc. We will always call textureFulfillProc and textureReleaseProc in pairs.
In other words we will never call textureFulfillProc or textureReleaseProc multiple times
for the same textureContext before calling the other.
We call the promiseDoneProc when we will no longer call the textureFulfillProc again. We
pass in the textureContext as a parameter to the promiseDoneProc. We also guarantee that
there will be no outstanding textureReleaseProcs that still need to be called when we call
the textureDoneProc. Thus when the textureDoneProc gets called the client is able to cleanup
all GPU objects and meta data needed for the textureFulfill call.
This call is only valid if the SkDeferredDisplayListRecorder is backed by a gpu context.
@param backendFormat format of promised gpu texture
@param width width of promised gpu texture
@param height height of promised gpu texture
@param mipMapped mip mapped state of promised gpu texture
@param origin one of: kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin
@param colorType one of: kUnknown_SkColorType, kAlpha_8_SkColorType,
kRGB_565_SkColorType, kARGB_4444_SkColorType,
kRGBA_8888_SkColorType, kBGRA_8888_SkColorType,
kGray_8_SkColorType, kRGBA_F16_SkColorType
@param alphaType one of: kUnknown_SkAlphaType, kOpaque_SkAlphaType,
kPremul_SkAlphaType, kUnpremul_SkAlphaType
@param colorSpace range of colors; may be nullptr
@param textureFulfillProc function called to get actual gpu texture
@param textureReleaseProc function called when texture can be released
@param promiseDoneProc function called when we will no longer call textureFulfillProc
@param textureContext state passed to textureFulfillProc and textureReleaseProc
@return created SkImage, or nullptr
*/
sk_sp<SkImage> makePromiseTexture(const GrBackendFormat& backendFormat,
int width,
int height,
GrMipMapped mipMapped,
GrSurfaceOrigin origin,
SkColorType colorType,
SkAlphaType alphaType,
sk_sp<SkColorSpace> colorSpace,
TextureFulfillProc textureFulfillProc,
TextureReleaseProc textureReleaseProc,
PromiseDoneProc promiseDoneProc,
TextureContext textureContext);
/**
This entry point operates the same as 'makePromiseTexture' except that its
textureFulfillProc can be called up to four times to fetch the required YUVA
planes (passing a different textureContext to each call). So, if the 'yuvaIndices'
indicate that only the first two backend textures are used, 'textureFulfillProc' will
be called with the first two 'textureContexts'.
*/
sk_sp<SkImage> makeYUVAPromiseTexture(SkYUVColorSpace yuvColorSpace,
const GrBackendFormat yuvaFormats[],
const SkISize yuvaSizes[],
const SkYUVAIndex yuvaIndices[4],
int imageWidth,
int imageHeight,
GrSurfaceOrigin imageOrigin,
sk_sp<SkColorSpace> imageColorSpace,
TextureFulfillProc textureFulfillProc,
TextureReleaseProc textureReleaseProc,
PromiseDoneProc promiseDoneProc,
TextureContext textureContexts[]);
// deprecated version that doesn't take yuvaSizeInfo
sk_sp<SkImage> makeYUVAPromiseTexture(SkYUVColorSpace yuvColorSpace,
const GrBackendFormat yuvaFormats[],
const SkYUVAIndex yuvaIndices[4],
int imageWidth,
int imageHeight,
GrSurfaceOrigin imageOrigin,
sk_sp<SkColorSpace> imageColorSpace,
TextureFulfillProc textureFulfillProc,
TextureReleaseProc textureReleaseProc,
PromiseDoneProc promiseDoneProc,
TextureContext textureContexts[]);
private:
bool init();
const SkSurfaceCharacterization fCharacterization;
#if SK_SUPPORT_GPU
sk_sp<GrContext> fContext;
sk_sp<SkDeferredDisplayList::LazyProxyData> fLazyProxyData;
sk_sp<SkSurface> fSurface;
#endif
};
#endif

139
skia/include/core/SkDeque.h vendored Normal file
View File

@ -0,0 +1,139 @@
/*
* 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 SkDeque_DEFINED
#define SkDeque_DEFINED
#include "../private/SkNoncopyable.h"
#include "SkTypes.h"
/*
* The deque class works by blindly creating memory space of a specified element
* size. It manages the memory as a doubly linked list of blocks each of which
* can contain multiple elements. Pushes and pops add/remove blocks from the
* beginning/end of the list as necessary while each block tracks the used
* portion of its memory.
* One behavior to be aware of is that the pops do not immediately remove an
* empty block from the beginning/end of the list (Presumably so push/pop pairs
* on the block boundaries don't cause thrashing). This can result in the first/
* last element not residing in the first/last block.
*/
class SK_API SkDeque : SkNoncopyable {
public:
/**
* elemSize specifies the size of each individual element in the deque
* allocCount specifies how many elements are to be allocated as a block
*/
explicit SkDeque(size_t elemSize, int allocCount = 1);
SkDeque(size_t elemSize, void* storage, size_t storageSize, int allocCount = 1);
~SkDeque();
bool empty() const { return 0 == fCount; }
int count() const { return fCount; }
size_t elemSize() const { return fElemSize; }
const void* front() const { return fFront; }
const void* back() const { return fBack; }
void* front() {
return (void*)((const SkDeque*)this)->front();
}
void* back() {
return (void*)((const SkDeque*)this)->back();
}
/**
* push_front and push_back return a pointer to the memory space
* for the new element
*/
void* push_front();
void* push_back();
void pop_front();
void pop_back();
private:
struct Block;
public:
class Iter {
public:
enum IterStart {
kFront_IterStart,
kBack_IterStart,
};
/**
* Creates an uninitialized iterator. Must be reset()
*/
Iter();
Iter(const SkDeque& d, IterStart startLoc);
void* next();
void* prev();
void reset(const SkDeque& d, IterStart startLoc);
private:
SkDeque::Block* fCurBlock;
char* fPos;
size_t fElemSize;
};
// Inherit privately from Iter to prevent access to reverse iteration
class F2BIter : private Iter {
public:
F2BIter() {}
/**
* Wrap Iter's 2 parameter ctor to force initialization to the
* beginning of the deque
*/
F2BIter(const SkDeque& d) : INHERITED(d, kFront_IterStart) {}
using Iter::next;
/**
* Wrap Iter::reset to force initialization to the beginning of the
* deque
*/
void reset(const SkDeque& d) {
this->INHERITED::reset(d, kFront_IterStart);
}
private:
typedef Iter INHERITED;
};
private:
// allow unit test to call numBlocksAllocated
friend class DequeUnitTestHelper;
void* fFront;
void* fBack;
Block* fFrontBlock;
Block* fBackBlock;
size_t fElemSize;
void* fInitialStorage;
int fCount; // number of elements in the deque
int fAllocCount; // number of elements to allocate per block
Block* allocateBlock(int allocCount);
void freeBlock(Block* block);
/**
* This returns the number of chunk blocks allocated by the deque. It
* can be used to gauge the effectiveness of the selected allocCount.
*/
int numBlocksAllocated() const;
};
#endif

91
skia/include/core/SkDocument.h vendored Normal file
View File

@ -0,0 +1,91 @@
/*
* Copyright 2013 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkDocument_DEFINED
#define SkDocument_DEFINED
#include "SkRefCnt.h"
#include "SkScalar.h"
class SkCanvas;
class SkWStream;
struct SkRect;
/** SK_ScalarDefaultDPI is 72 dots per inch. */
static constexpr SkScalar SK_ScalarDefaultRasterDPI = 72.0f;
/**
* High-level API for creating a document-based canvas. To use..
*
* 1. Create a document, specifying a stream to store the output.
* 2. For each "page" of content:
* a. canvas = doc->beginPage(...)
* b. draw_my_content(canvas);
* c. doc->endPage();
* 3. Close the document with doc->close().
*/
class SK_API SkDocument : public SkRefCnt {
public:
/**
* Begin a new page for the document, returning the canvas that will draw
* into the page. The document owns this canvas, and it will go out of
* scope when endPage() or close() is called, or the document is deleted.
*/
SkCanvas* beginPage(SkScalar width, SkScalar height, const SkRect* content = nullptr);
/**
* Call endPage() when the content for the current page has been drawn
* (into the canvas returned by beginPage()). After this call the canvas
* returned by beginPage() will be out-of-scope.
*/
void endPage();
/**
* Call close() when all pages have been drawn. This will close the file
* or stream holding the document's contents. After close() the document
* can no longer add new pages. Deleting the document will automatically
* call close() if need be.
*/
void close();
/**
* Call abort() to stop producing the document immediately.
* The stream output must be ignored, and should not be trusted.
*/
void abort();
protected:
SkDocument(SkWStream*);
// note: subclasses must call close() in their destructor, as the base class
// cannot do this for them.
virtual ~SkDocument();
virtual SkCanvas* onBeginPage(SkScalar width, SkScalar height) = 0;
virtual void onEndPage() = 0;
virtual void onClose(SkWStream*) = 0;
virtual void onAbort() = 0;
// Allows subclasses to write to the stream as pages are written.
SkWStream* getStream() { return fStream; }
enum State {
kBetweenPages_State,
kInPage_State,
kClosed_State
};
State getState() const { return fState; }
private:
SkWStream* fStream;
State fState;
typedef SkRefCnt INHERITED;
};
#endif

129
skia/include/core/SkDrawLooper.h vendored Normal file
View File

@ -0,0 +1,129 @@
/*
* Copyright 2011 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 SkDrawLooper_DEFINED
#define SkDrawLooper_DEFINED
#include "../private/SkNoncopyable.h"
#include "SkBlurTypes.h"
#include "SkFlattenable.h"
#include "SkPoint.h"
#include "SkColor.h"
class SkArenaAlloc;
class SkCanvas;
class SkColorSpaceXformer;
class SkPaint;
struct SkRect;
class SkString;
/** \class SkDrawLooper
Subclasses of SkDrawLooper can be attached to a SkPaint. Where they are,
and something is drawn to a canvas with that paint, the looper subclass will
be called, allowing it to modify the canvas and/or paint for that draw call.
More than that, via the next() method, the looper can modify the draw to be
invoked multiple times (hence the name loop-er), allow it to perform effects
like shadows or frame/fills, that require more than one pass.
*/
class SK_API SkDrawLooper : public SkFlattenable {
public:
/**
* Holds state during a draw. Users call next() until it returns false.
*
* Subclasses of SkDrawLooper should create a subclass of this object to
* hold state specific to their subclass.
*/
class SK_API Context : ::SkNoncopyable {
public:
Context() {}
virtual ~Context() {}
/**
* Called in a loop on objects returned by SkDrawLooper::createContext().
* Each time true is returned, the object is drawn (possibly with a modified
* canvas and/or paint). When false is finally returned, drawing for the object
* stops.
*
* On each call, the paint will be in its original state, but the
* canvas will be as it was following the previous call to next() or
* createContext().
*
* The implementation must ensure that, when next() finally returns
* false, the canvas has been restored to the state it was
* initially, before createContext() was first called.
*/
virtual bool next(SkCanvas* canvas, SkPaint* paint) = 0;
};
/**
* Called right before something is being drawn. Returns a Context
* whose next() method should be called until it returns false.
*/
virtual Context* makeContext(SkCanvas*, SkArenaAlloc*) const = 0;
/**
* The fast bounds functions are used to enable the paint to be culled early
* in the drawing pipeline. If a subclass can support this feature it must
* return true for the canComputeFastBounds() function. If that function
* returns false then computeFastBounds behavior is undefined otherwise it
* is expected to have the following behavior. Given the parent paint and
* the parent's bounding rect the subclass must fill in and return the
* storage rect, where the storage rect is with the union of the src rect
* and the looper's bounding rect.
*/
bool canComputeFastBounds(const SkPaint& paint) const;
void computeFastBounds(const SkPaint& paint, const SkRect& src, SkRect* dst) const;
struct BlurShadowRec {
SkScalar fSigma;
SkVector fOffset;
SkColor fColor;
SkBlurStyle fStyle;
};
/**
* If this looper can be interpreted as having two layers, such that
* 1. The first layer (bottom most) just has a blur and translate
* 2. The second layer has no modifications to either paint or canvas
* 3. No other layers.
* then return true, and if not null, fill out the BlurShadowRec).
*
* If any of the above are not met, return false and ignore the BlurShadowRec parameter.
*/
virtual bool asABlurShadow(BlurShadowRec*) const;
static SkFlattenable::Type GetFlattenableType() {
return kSkDrawLooper_Type;
}
SkFlattenable::Type getFlattenableType() const override {
return kSkDrawLooper_Type;
}
static sk_sp<SkDrawLooper> Deserialize(const void* data, size_t size,
const SkDeserialProcs* procs = nullptr) {
return sk_sp<SkDrawLooper>(static_cast<SkDrawLooper*>(
SkFlattenable::Deserialize(
kSkDrawLooper_Type, data, size, procs).release()));
}
protected:
sk_sp<SkDrawLooper> makeColorSpace(SkColorSpaceXformer* xformer) const {
return this->onMakeColorSpace(xformer);
}
virtual sk_sp<SkDrawLooper> onMakeColorSpace(SkColorSpaceXformer*) const = 0;
SkDrawLooper() {}
private:
friend class SkColorSpaceXformer;
typedef SkFlattenable INHERITED;
};
#endif

150
skia/include/core/SkDrawable.h vendored Normal file
View File

@ -0,0 +1,150 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkDrawable_DEFINED
#define SkDrawable_DEFINED
#include "SkFlattenable.h"
#include "SkScalar.h"
class GrBackendDrawableInfo;
class SkCanvas;
class SkMatrix;
class SkPicture;
enum class GrBackendApi : unsigned;
struct SkRect;
/**
* Base-class for objects that draw into SkCanvas.
*
* The object has a generation ID, which is guaranteed to be unique across all drawables. To
* allow for clients of the drawable that may want to cache the results, the drawable must
* change its generation ID whenever its internal state changes such that it will draw differently.
*/
class SK_API SkDrawable : public SkFlattenable {
public:
/**
* Draws into the specified content. The drawing sequence will be balanced upon return
* (i.e. the saveLevel() on the canvas will match what it was when draw() was called,
* and the current matrix and clip settings will not be changed.
*/
void draw(SkCanvas*, const SkMatrix* = nullptr);
void draw(SkCanvas*, SkScalar x, SkScalar y);
/**
* When using the GPU backend it is possible for a drawable to execute using the underlying 3D
* API rather than the SkCanvas API. It does so by creating a GpuDrawHandler. The GPU backend
* is deferred so the handler will be given access to the 3D API at the correct point in the
* drawing stream as the GPU backend flushes. Since the drawable may mutate, each time it is
* drawn to a GPU-backed canvas a new handler is snapped, representing the drawable's state at
* the time of the snap.
*
* When the GPU backend flushes to the 3D API it will call the draw method on the
* GpuDrawHandler. At this time the drawable may add commands to the stream of GPU commands for
* the unerlying 3D API. The draw function takes a GrBackendDrawableInfo which contains
* information about the current state of 3D API which the caller must respect. See
* GrBackendDrawableInfo for more specific details on what information is sent and the
* requirements for different 3D APIs.
*
* Additionaly there may be a slight delay from when the drawable adds its commands to when
* those commands are actually submitted to the GPU. Thus the drawable or GpuDrawHandler is
* required to keep any resources that are used by its added commands alive and valid until
* those commands are submitted to the GPU. The GpuDrawHandler will be kept alive and then
* deleted once the commands are submitted to the GPU. The dtor of the GpuDrawHandler is the
* signal to the drawable that the commands have all been submitted. Different 3D APIs may have
* additional requirements for certain resources which require waiting for the GPU to finish
* all work on those resources before reusing or deleting them. In this case, the drawable can
* use the dtor call of the GpuDrawHandler to add a fence to the GPU to track when the GPU work
* has completed.
*
* Currently this is only supported for the GPU Vulkan backend.
*/
class GpuDrawHandler {
public:
virtual ~GpuDrawHandler() {}
virtual void draw(const GrBackendDrawableInfo&) {}
};
/**
* Snaps off a GpuDrawHandler to represent the state of the SkDrawable at the time the snap is
* called. This is used for executing GPU backend specific draws intermixed with normal Skia GPU
* draws. The GPU API, which will be used for the draw, as well as the full matrix are passed in
* as inputs.
*/
std::unique_ptr<GpuDrawHandler> snapGpuDrawHandler(GrBackendApi backendApi,
const SkMatrix& matrix) {
return this->onSnapGpuDrawHandler(backendApi, matrix);
}
SkPicture* newPictureSnapshot();
/**
* Return a unique value for this instance. If two calls to this return the same value,
* it is presumed that calling the draw() method will render the same thing as well.
*
* Subclasses that change their state should call notifyDrawingChanged() to ensure that
* a new value will be returned the next time it is called.
*/
uint32_t getGenerationID();
/**
* Return the (conservative) bounds of what the drawable will draw. If the drawable can
* change what it draws (e.g. animation or in response to some external change), then this
* must return a bounds that is always valid for all possible states.
*/
SkRect getBounds();
/**
* Calling this invalidates the previous generation ID, and causes a new one to be computed
* the next time getGenerationID() is called. Typically this is called by the object itself,
* in response to its internal state changing.
*/
void notifyDrawingChanged();
static SkFlattenable::Type GetFlattenableType() {
return kSkDrawable_Type;
}
SkFlattenable::Type getFlattenableType() const override {
return kSkDrawable_Type;
}
static sk_sp<SkDrawable> Deserialize(const void* data, size_t size,
const SkDeserialProcs* procs = nullptr) {
return sk_sp<SkDrawable>(static_cast<SkDrawable*>(
SkFlattenable::Deserialize(
kSkDrawable_Type, data, size, procs).release()));
}
Factory getFactory() const override { return nullptr; }
const char* getTypeName() const override { return nullptr; }
protected:
SkDrawable();
virtual SkRect onGetBounds() = 0;
virtual void onDraw(SkCanvas*) = 0;
virtual std::unique_ptr<GpuDrawHandler> onSnapGpuDrawHandler(GrBackendApi, const SkMatrix&) {
return nullptr;
}
/**
* Default implementation calls onDraw() with a canvas that records into a picture. Subclasses
* may override if they have a more efficient way to return a picture for the current state
* of their drawable. Note: this picture must draw the same as what would be drawn from
* onDraw().
*/
virtual SkPicture* onNewPictureSnapshot();
private:
int32_t fGenerationID;
};
#endif

View File

@ -0,0 +1,34 @@
/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkEncodedImageFormat_DEFINED
#define SkEncodedImageFormat_DEFINED
#include <stdint.h>
/**
* Enum describing format of encoded data.
*/
enum class SkEncodedImageFormat {
#ifdef SK_BUILD_FOR_GOOGLE3
kUnknown,
#endif
kBMP,
kGIF,
kICO,
kJPEG,
kPNG,
kWBMP,
kWEBP,
kPKM,
kKTX,
kASTC,
kDNG,
kHEIF,
};
#endif // SkEncodedImageFormat_DEFINED

33
skia/include/core/SkExecutor.h vendored Normal file
View File

@ -0,0 +1,33 @@
/*
* Copyright 2017 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkExecutor_DEFINED
#define SkExecutor_DEFINED
#include <functional>
#include <memory>
class SkExecutor {
public:
virtual ~SkExecutor();
// Create a thread pool SkExecutor with a fixed thread count, by default the number of cores.
static std::unique_ptr<SkExecutor> MakeFIFOThreadPool(int threads = 0);
static std::unique_ptr<SkExecutor> MakeLIFOThreadPool(int threads = 0);
// There is always a default SkExecutor available by calling SkExecutor::GetDefault().
static SkExecutor& GetDefault();
static void SetDefault(SkExecutor*); // Does not take ownership. Not thread safe.
// Add work to execute.
virtual void add(std::function<void(void)>) = 0;
// If it makes sense for this executor, use this thread to execute work for a little while.
virtual void borrow() {}
};
#endif//SkExecutor_DEFINED

26
skia/include/core/SkFilterQuality.h vendored Normal file
View File

@ -0,0 +1,26 @@
/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkFilterQuality_DEFINED
#define SkFilterQuality_DEFINED
#include "SkTypes.h"
/**
* Controls how much filtering to be done when scaling/transforming complex colors
* e.g. images
*/
enum SkFilterQuality {
kNone_SkFilterQuality, //!< fastest but lowest quality, typically nearest-neighbor
kLow_SkFilterQuality, //!< typically bilerp
kMedium_SkFilterQuality, //!< typically bilerp + mipmaps for down-scaling
kHigh_SkFilterQuality, //!< slowest but highest quality, typically bicubic or better
kLast_SkFilterQuality = kHigh_SkFilterQuality,
};
#endif

107
skia/include/core/SkFlattenable.h vendored Normal file
View File

@ -0,0 +1,107 @@
/*
* Copyright 2006 The Android Open Source Project
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkFlattenable_DEFINED
#define SkFlattenable_DEFINED
#include "SkRefCnt.h"
class SkData;
class SkReadBuffer;
class SkWriteBuffer;
struct SkSerialProcs;
struct SkDeserialProcs;
/** \class SkFlattenable
SkFlattenable is the base class for objects that need to be flattened
into a data stream for either transport or as part of the key to the
font cache.
*/
class SK_API SkFlattenable : public SkRefCnt {
public:
enum Type {
kSkColorFilter_Type,
kSkDrawable_Type,
kSkDrawLooper_Type,
kSkImageFilter_Type,
kSkMaskFilter_Type,
kSkPathEffect_Type,
kSkPixelRef_Type,
kSkUnused_Type4, // used to be SkRasterizer
kSkShaderBase_Type,
kSkUnused_Type, // used to be SkUnitMapper
kSkUnused_Type2,
kSkNormalSource_Type,
};
typedef sk_sp<SkFlattenable> (*Factory)(SkReadBuffer&);
SkFlattenable() {}
/** Implement this to return a factory function pointer that can be called
to recreate your class given a buffer (previously written to by your
override of flatten().
*/
virtual Factory getFactory() const = 0;
/**
* Returns the name of the object's class.
*/
virtual const char* getTypeName() const = 0;
static Factory NameToFactory(const char name[]);
static const char* FactoryToName(Factory);
static void Register(const char name[], Factory);
/**
* Override this if your subclass needs to record data that it will need to recreate itself
* from its CreateProc (returned by getFactory()).
*
* DEPRECATED public : will move to protected ... use serialize() instead
*/
virtual void flatten(SkWriteBuffer&) const {}
virtual Type getFlattenableType() const = 0;
//
// public ways to serialize / deserialize
//
sk_sp<SkData> serialize(const SkSerialProcs* = nullptr) const;
size_t serialize(void* memory, size_t memory_size,
const SkSerialProcs* = nullptr) const;
static sk_sp<SkFlattenable> Deserialize(Type, const void* data, size_t length,
const SkDeserialProcs* procs = nullptr);
protected:
class PrivateInitializer {
public:
static void InitEffects();
static void InitImageFilters();
};
private:
static void RegisterFlattenablesIfNeeded();
static void Finalize();
friend class SkGraphics;
typedef SkRefCnt INHERITED;
};
#define SK_REGISTER_FLATTENABLE(type) \
SkFlattenable::Register(#type, type::CreateProc);
#define SK_FLATTENABLE_HOOKS(type) \
static sk_sp<SkFlattenable> CreateProc(SkReadBuffer&); \
friend class SkFlattenable::PrivateInitializer; \
Factory getFactory() const override { return type::CreateProc; } \
const char* getTypeName() const override { return #type; }
#endif

488
skia/include/core/SkFont.h vendored Normal file
View File

@ -0,0 +1,488 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkFont_DEFINED
#define SkFont_DEFINED
#include "SkFontTypes.h"
#include "SkScalar.h"
#include "SkTypeface.h"
class SkMatrix;
class SkPaint;
class SkPath;
struct SkFontMetrics;
/** \class SkFont
SkFont controls options applied when drawing and measuring text.
*/
class SK_API SkFont {
public:
/** Whether edge pixels draw opaque or with partial transparency.
*/
enum class Edging {
kAlias, //!< no transparent pixels on glyph edges
kAntiAlias, //!< may have transparent pixels on glyph edges
kSubpixelAntiAlias, //!< glyph positioned in pixel using transparency
};
#ifdef SK_SUPPORT_LEGACY_NESTED_HINTINGENUM
/** Amount of font hinting applied to glyph outlines.
*/
enum Hinting : uint8_t {
kNo_Hinting = 0, //!< glyph outlines unchanged
kSlight_Hinting = 1, //!< minimal modification to improve constrast
kNormal_Hinting = 2, //!< glyph outlines modified to improve constrast
kFull_Hinting = 3, //!< modifies glyph outlines for maximum constrast
};
#endif
/** Constructs SkFont with default values.
@return default initialized SkFont
*/
SkFont();
/** Constructs SkFont with default values with SkTypeface and size in points.
@param typeface font and style used to draw and measure text
@param size typographic height of text
@return initialized SkFont
*/
SkFont(sk_sp<SkTypeface> typeface, SkScalar size);
/** Constructs SkFont with default values with SkTypeface and size in points,
horizontal scale, and horizontal skew. Horizontal scale emulates condensed
and expanded fonts. Horizontal skew emulates oblique fonts.
@param typeface font and style used to draw and measure text
@param size typographic height of text
@param scaleX text horizontal scale
@param skewX additional shear on x-axis relative to y-axis
@return initialized SkFont
*/
SkFont(sk_sp<SkTypeface> typeface, SkScalar size, SkScalar scaleX, SkScalar skewX);
/** Compares SkFont and font, and returns true if they are equivalent.
May return false if SkTypeface has identical contents but different pointers.
@param font SkPaint to compare
@return true if SkFont pair are equivalent
*/
bool operator==(const SkFont& font) const;
/** If true, instructs the font manager to always hint glyphs.
Returned value is only meaningful if platform uses FreeType as the font manager.
@return true if all glyphs are hinted
*/
bool isForceAutoHinting() const { return SkToBool(fFlags & kForceAutoHinting_PrivFlag); }
/** Returns true if font engine may return glyphs from font bitmaps instead of from outlines.
@return true if glyphs may be font bitmaps
*/
bool isEmbeddedBitmaps() const { return SkToBool(fFlags & kEmbeddedBitmaps_PrivFlag); }
/** Returns true if glyphs at different sub-pixel positions may differ on pixel edge coverage.
@return true if glyph positioned in pixel using transparency
*/
bool isSubpixel() const { return SkToBool(fFlags & kSubpixel_PrivFlag); }
/** Returns true if text is converted to SkPath before drawing and measuring.
@return true glyph hints are never applied
*/
bool isLinearMetrics() const { return SkToBool(fFlags & kLinearMetrics_PrivFlag); }
/** Returns true if bold is approximated by increasing the stroke width when creating glyph
bitmaps from outlines.
@return bold is approximated through stroke width
*/
bool isEmbolden() const { return SkToBool(fFlags & kEmbolden_PrivFlag); }
/** Sets whether to always hint glyphs.
If forceAutoHinting is set, instructs the font manager to always hint glyphs.
Only affects platforms that use FreeType as the font manager.
@param forceAutoHinting setting to always hint glyphs
*/
void setForceAutoHinting(bool forceAutoHinting);
/** Requests, but does not require, to use bitmaps in fonts instead of outlines.
@param embeddedBitmaps setting to use bitmaps in fonts
*/
void setEmbeddedBitmaps(bool embeddedBitmaps);
/** Requests, but does not require, that glyphs respect sub-pixel positioning.
@param subpixel setting for sub-pixel positioning
*/
void setSubpixel(bool subpixel);
/** Requests, but does not require, that glyphs are converted to SkPath
before drawing and measuring.
@param linearMetrics setting for converting glyphs to paths
*/
void setLinearMetrics(bool linearMetrics);
/** Increases stroke width when creating glyph bitmaps to approximate a bold typeface.
@param embolden setting for bold approximation
*/
void setEmbolden(bool embolden);
/** Whether edge pixels draw opaque or with partial transparency.
@return one of: Edging::kAlias, Edging::kAntiAlias, Edging::kSubpixelAntiAlias
*/
Edging getEdging() const { return (Edging)fEdging; }
/** Requests, but does not require, that edge pixels draw opaque or with
partial transparency.
@param edging one of: Edging::kAlias, Edging::kAntiAlias, Edging::kSubpixelAntiAlias
*/
void setEdging(Edging edging);
/** Sets level of glyph outline adjustment.
Does not check for valid values of hintingLevel.
@param hintingLevel one of: SkFontHinting::kNone, SkFontHinting::kSlight,
SkFontHinting::kNormal, SkFontHinting::kFull
*/
void setHinting(SkFontHinting hintingLevel);
/** Returns level of glyph outline adjustment.
@return one of: SkFontHinting::kNone, SkFontHinting::kSlight, SkFontHinting::kNormal,
SkFontHinting::kFull
*/
SkFontHinting getHinting() const { return (SkFontHinting)fHinting; }
/** Returns a font with the same attributes of this font, but with the specified size.
Returns nullptr if size is less than zero, infinite, or NaN.
@param size typographic height of text
@return initialized SkFont
*/
SkFont makeWithSize(SkScalar size) const;
/** Returns SkTypeface if set, or nullptr.
Does not alter SkTypeface SkRefCnt.
@return SkTypeface if previously set, nullptr otherwise
*/
SkTypeface* getTypeface() const { return fTypeface.get(); }
/** Returns text size in points.
@return typographic height of text
*/
SkScalar getSize() const { return fSize; }
/** Returns text scale on x-axis.
Default value is 1.
@return text horizontal scale
*/
SkScalar getScaleX() const { return fScaleX; }
/** Returns text skew on x-axis.
Default value is zero.
@return additional shear on x-axis relative to y-axis
*/
SkScalar getSkewX() const { return fSkewX; }
/** Increases SkTypeface SkRefCnt by one.
@return SkTypeface if previously set, nullptr otherwise
*/
sk_sp<SkTypeface> refTypeface() const { return fTypeface; }
/** Sets SkTypeface to typeface, decreasing SkRefCnt of the previous SkTypeface.
Pass nullptr to clear SkTypeface and use the default typeface. Increments
tf SkRefCnt by one.
@param tf font and style used to draw text
*/
void setTypeface(sk_sp<SkTypeface> tf) { fTypeface = tf; }
/** Sets text size in points.
Has no effect if textSize is not greater than or equal to zero.
@param textSize typographic height of text
*/
void setSize(SkScalar textSize);
/** Sets text scale on x-axis.
Default value is 1.
@param scaleX text horizontal scale
*/
void setScaleX(SkScalar scaleX);
/** Sets text skew on x-axis.
Default value is zero.
@param skewX additional shear on x-axis relative to y-axis
*/
void setSkewX(SkScalar skewX);
/** Converts text into glyph indices.
Returns the number of glyph indices represented by text.
SkTextEncoding specifies how text represents characters or glyphs.
glyphs may be nullptr, to compute the glyph count.
Does not check text for valid character codes or valid glyph indices.
If byteLength equals zero, returns zero.
If byteLength includes a partial character, the partial character is ignored.
If encoding is kUTF8_SkTextEncoding and text contains an invalid UTF-8 sequence,
zero is returned.
If maxGlyphCount is not sufficient to store all the glyphs, no glyphs are copied.
The total glyph count is returned for subsequent buffer reallocation.
@param text character storage encoded with SkPaint::TextEncoding
@param byteLength length of character storage in bytes
@param encoding one of: kUTF8_SkTextEncoding, kUTF16_SkTextEncoding,
kUTF32_SkTextEncoding, kGlyphID_SkTextEncoding
@param glyphs storage for glyph indices; may be nullptr
@param maxGlyphCount storage capacity
@return number of glyphs represented by text of length byteLength
*/
int textToGlyphs(const void* text, size_t byteLength, SkTextEncoding encoding,
SkGlyphID glyphs[], int maxGlyphCount) const;
/** Returns glyph index for Unicode character.
@param uni Unicode character
@return glyph index
*/
uint16_t unicharToGlyph(SkUnichar uni) const {
return fTypeface->unicharToGlyph(uni);
}
/** Returns number of glyphs represented by text.
@param text character storage encoded with SkPaint::TextEncoding
@param byteLength length of character storage in bytes
@param encoding one of: kUTF8_SkTextEncoding, kUTF16_SkTextEncoding,
kUTF32_SkTextEncoding, kGlyphID_SkTextEncoding
@return number of glyphs represented by text of length byteLength
*/
int countText(const void* text, size_t byteLength, SkTextEncoding encoding) const {
return this->textToGlyphs(text, byteLength, encoding, nullptr, 0);
}
/** Returns true if all text corresponds to a non-zero glyph index.
Returns false if any characters in text are not supported in
SkTypeface.
If SkTextEncoding is kGlyphID_SkTextEncoding,
returns true if all glyph indices in text are non-zero;
does not check to see if text contains valid glyph indices for SkTypeface.
Returns true if byteLength is zero.
@param text array of characters or glyphs
@param byteLength number of bytes in text array
@param encoding text encoding
@return true if all text corresponds to a non-zero glyph index
*/
bool containsText(const void* text, size_t byteLength, SkTextEncoding encoding) const;
/** Returns the advance width of text.
The advance is the normal distance to move before drawing additional text.
Returns the bounding box of text if bounds is not nullptr.
@param text character storage encoded with SkPaint::TextEncoding
@param byteLength length of character storage in bytes
@param encoding one of: kUTF8_SkTextEncoding, kUTF16_SkTextEncoding,
kUTF32_SkTextEncoding, kGlyphID_SkTextEncoding
@param bounds returns bounding box relative to (0, 0) if not nullptr
@return number of glyphs represented by text of length byteLength
*/
SkScalar measureText(const void* text, size_t byteLength, SkTextEncoding encoding,
SkRect* bounds = nullptr) const;
/** DEPRECATED
Retrieves the advance and bounds for each glyph in glyphs.
Both widths and bounds may be nullptr.
If widths is not nullptr, widths must be an array of count entries.
if bounds is not nullptr, bounds must be an array of count entries.
@param glyphs array of glyph indices to be measured
@param count number of glyphs
@param widths returns text advances for each glyph; may be nullptr
@param bounds returns bounds for each glyph relative to (0, 0); may be nullptr
*/
void getWidths(const uint16_t glyphs[], int count, SkScalar widths[], SkRect bounds[]) const {
this->getWidthsBounds(glyphs, count, widths, bounds, nullptr);
}
// DEPRECATED
void getWidths(const uint16_t glyphs[], int count, SkScalar widths[], std::nullptr_t) const {
this->getWidths(glyphs, count, widths);
}
/** Experimental
Retrieves the advance and bounds for each glyph in glyphs.
Both widths and bounds may be nullptr.
If widths is not nullptr, widths must be an array of count entries.
if bounds is not nullptr, bounds must be an array of count entries.
@param glyphs array of glyph indices to be measured
@param count number of glyphs
@param widths returns text advances for each glyph
*/
void getWidths(const uint16_t glyphs[], int count, SkScalar widths[]) const {
this->getWidthsBounds(glyphs, count, widths, nullptr, nullptr);
}
/** Experimental.
Retrieves the advance and bounds for each glyph in glyphs.
Both widths and bounds may be nullptr.
If widths is not nullptr, widths must be an array of count entries.
if bounds is not nullptr, bounds must be an array of count entries.
@param glyphs array of glyph indices to be measured
@param count number of glyphs
@param widths returns text advances for each glyph; may be nullptr
@param bounds returns bounds for each glyph relative to (0, 0); may be nullptr
@param paint optional, specifies stroking, patheffect and maskfilter
*/
void getWidthsBounds(const uint16_t glyphs[], int count, SkScalar widths[], SkRect bounds[],
const SkPaint* paint) const;
/** Experimental.
Retrieves the bounds for each glyph in glyphs.
bounds must be an array of count entries.
If paint is not nullptr, its stroking, patheffect and maskfilter fields will be respected.
@param glyphs array of glyph indices to be measured
@param count number of glyphs
@param bounds returns bounds for each glyph relative to (0, 0); may be nullptr
@param paint optional, specifies stroking, patheffect and maskfilter
*/
void getBounds(const uint16_t glyphs[], int count, SkRect bounds[], const SkPaint* paint) const {
this->getWidthsBounds(glyphs, count, nullptr, bounds, paint);
}
/** Experimental
Retrieves the positions for each glyph, beginning at the specified origin. The caller
must allocated at least count number of elements in the pos[] array.
@param glyphs array of glyph indices to be positioned
@param count number of glyphs
@param pos returns glyphs positions
@param origin location of the first glyph. Defaults to {0, 0}.
*/
void getPos(const uint16_t glyphs[], int count, SkPoint pos[], SkPoint origin = {0, 0}) const;
/** Experimental
Retrieves the x-positions for each glyph, beginning at the specified origin. The caller
must allocated at least count number of elements in the xpos[] array.
@param glyphs array of glyph indices to be positioned
@param count number of glyphs
@param xpos returns glyphs x-positions
@param origin x-position of the first glyph. Defaults to 0.
*/
void getXPos(const uint16_t glyphs[], int count, SkScalar xpos[], SkScalar origin = 0) const;
/** Returns path corresponding to glyph outline.
If glyph has an outline, copies outline to path and returns true.
path returned may be empty.
If glyph is described by a bitmap, returns false and ignores path parameter.
@param glyphID index of glyph
@param path pointer to existing SkPath
@return true if glyphID is described by path
*/
bool getPath(uint16_t glyphID, SkPath* path) const;
/** Returns path corresponding to glyph array.
@param glyphIDs array of glyph indices
@param count number of glyphs
@param glyphPathProc function returning one glyph description as path
@param ctx function context
*/
void getPaths(const uint16_t glyphIDs[], int count,
void (*glyphPathProc)(const SkPath* pathOrNull, const SkMatrix& mx, void* ctx),
void* ctx) const;
/** Returns SkFontMetrics associated with SkTypeface.
The return value is the recommended spacing between lines: the sum of metrics
descent, ascent, and leading.
If metrics is not nullptr, SkFontMetrics is copied to metrics.
Results are scaled by text size but does not take into account
dimensions required by text scale, text skew, fake bold,
style stroke, and SkPathEffect.
@param metrics storage for SkFontMetrics; may be nullptr
@return recommended spacing between lines
*/
SkScalar getMetrics(SkFontMetrics* metrics) const;
/** Returns the recommended spacing between lines: the sum of metrics
descent, ascent, and leading.
Result is scaled by text size but does not take into account
dimensions required by stroking and SkPathEffect.
Returns the same result as getMetrics().
@return recommended spacing between lines
*/
SkScalar getSpacing() const { return this->getMetrics(nullptr); }
/** Deprecated.
*/
void LEGACY_applyToPaint(SkPaint* paint) const;
/** Deprecated.
*/
void LEGACY_applyPaintFlags(uint32_t paintFlags);
/** Deprecated.
*/
static SkFont LEGACY_ExtractFromPaint(const SkPaint& paint);
private:
enum PrivFlags {
kForceAutoHinting_PrivFlag = 1 << 0,
kEmbeddedBitmaps_PrivFlag = 1 << 1,
kSubpixel_PrivFlag = 1 << 2,
kLinearMetrics_PrivFlag = 1 << 3,
kEmbolden_PrivFlag = 1 << 4,
};
static constexpr unsigned kAllFlags = 0x07F;
sk_sp<SkTypeface> fTypeface;
SkScalar fSize;
SkScalar fScaleX;
SkScalar fSkewX;
uint8_t fFlags;
uint8_t fEdging;
uint8_t fHinting;
SkScalar setupForAsPaths(SkPaint*);
friend class SkCanonicalizeFont;
};
#endif

79
skia/include/core/SkFontArguments.h vendored Normal file
View File

@ -0,0 +1,79 @@
/*
* Copyright 2017 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkFontArguments_DEFINED
#define SkFontArguments_DEFINED
#include "SkScalar.h"
#include "SkTypes.h"
/** Represents a set of actual arguments for a font. */
struct SkFontArguments {
struct VariationPosition {
struct Coordinate {
SkFourByteTag axis;
float value;
};
const Coordinate* coordinates;
int coordinateCount;
};
// deprecated, use VariationPosition::Coordinate instead
struct Axis {
SkFourByteTag fTag;
float fStyleValue;
};
SkFontArguments() : fCollectionIndex(0), fVariationDesignPosition{nullptr, 0} {}
/** Specify the index of the desired font.
*
* Font formats like ttc, dfont, cff, cid, pfr, t42, t1, and fon may actually be indexed
* collections of fonts.
*/
SkFontArguments& setCollectionIndex(int collectionIndex) {
fCollectionIndex = collectionIndex;
return *this;
}
// deprecated, use setVariationDesignPosition instead.
SkFontArguments& setAxes(const Axis* axes, int axisCount) {
fVariationDesignPosition.coordinates =
reinterpret_cast<const VariationPosition::Coordinate*>(axes);
fVariationDesignPosition.coordinateCount = axisCount;
return *this;
}
/** Specify a position in the variation design space.
*
* Any axis not specified will use the default value.
* Any specified axis not actually present in the font will be ignored.
*
* @param position not copied. The value must remain valid for life of SkFontArguments.
*/
SkFontArguments& setVariationDesignPosition(VariationPosition position) {
fVariationDesignPosition.coordinates = position.coordinates;
fVariationDesignPosition.coordinateCount = position.coordinateCount;
return *this;
}
int getCollectionIndex() const {
return fCollectionIndex;
}
// deprecated, use getVariationDesignPosition instead.
const Axis* getAxes(int* axisCount) const {
*axisCount = fVariationDesignPosition.coordinateCount;
return reinterpret_cast<const Axis*>(fVariationDesignPosition.coordinates);
}
VariationPosition getVariationDesignPosition() const {
return fVariationDesignPosition;
}
private:
int fCollectionIndex;
VariationPosition fVariationDesignPosition;
};
#endif

58
skia/include/core/SkFontLCDConfig.h vendored Normal file
View File

@ -0,0 +1,58 @@
/*
* 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 SkFontLCDConfig_DEFINED
#define SkFontLCDConfig_DEFINED
#include "SkTypes.h"
class SK_API SkFontLCDConfig {
public:
/** LCDs either have their color elements arranged horizontally or
vertically. When rendering subpixel glyphs we need to know which way
round they are.
Note, if you change this after startup, you'll need to flush the glyph
cache because it'll have the wrong type of masks cached.
@deprecated use SkPixelGeometry instead.
*/
enum LCDOrientation {
kHorizontal_LCDOrientation = 0, //!< this is the default
kVertical_LCDOrientation = 1,
};
/** @deprecated set on Device creation. */
static void SetSubpixelOrientation(LCDOrientation orientation);
/** @deprecated get from Device. */
static LCDOrientation GetSubpixelOrientation();
/** LCD color elements can vary in order. For subpixel text we need to know
the order which the LCDs uses so that the color fringes are in the
correct place.
Note, if you change this after startup, you'll need to flush the glyph
cache because it'll have the wrong type of masks cached.
kNONE_LCDOrder means that the subpixel elements are not spatially
separated in any usable fashion.
@deprecated use SkPixelGeometry instead.
*/
enum LCDOrder {
kRGB_LCDOrder = 0, //!< this is the default
kBGR_LCDOrder = 1,
kNONE_LCDOrder = 2,
};
/** @deprecated set on Device creation. */
static void SetSubpixelOrder(LCDOrder order);
/** @deprecated get from Device. */
static LCDOrder GetSubpixelOrder();
};
#endif

106
skia/include/core/SkFontMetrics.h vendored Normal file
View File

@ -0,0 +1,106 @@
/*
* Copyright 2018 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkFontMetrics_DEFINED
#define SkFontMetrics_DEFINED
#include "SkScalar.h"
struct SK_API SkFontMetrics {
/** \enum FontMetricsFlags
FontMetricsFlags are set in fFlags when underline and strikeout metrics are valid;
the underline or strikeout metric may be valid and zero.
Fonts with embedded bitmaps may not have valid underline or strikeout metrics.
*/
enum FontMetricsFlags {
kUnderlineThicknessIsValid_Flag = 1 << 0, //!< set if fUnderlineThickness is valid
kUnderlinePositionIsValid_Flag = 1 << 1, //!< set if fUnderlinePosition is valid
kStrikeoutThicknessIsValid_Flag = 1 << 2, //!< set if fStrikeoutThickness is valid
kStrikeoutPositionIsValid_Flag = 1 << 3, //!< set if fStrikeoutPosition is valid
};
uint32_t fFlags; //!< is set to FontMetricsFlags when metrics are valid
SkScalar fTop; //!< extent above baseline
SkScalar fAscent; //!< distance to reserve above baseline
SkScalar fDescent; //!< distance to reserve below baseline
SkScalar fBottom; //!< extent below baseline
SkScalar fLeading; //!< distance to add between lines
SkScalar fAvgCharWidth; //!< average character width
SkScalar fMaxCharWidth; //!< maximum character width
SkScalar fXMin; //!< minimum x
SkScalar fXMax; //!< maximum x
SkScalar fXHeight; //!< height of lower-case 'x'
SkScalar fCapHeight; //!< height of an upper-case letter
SkScalar fUnderlineThickness; //!< underline thickness
SkScalar fUnderlinePosition; //!< underline position relative to baseline
SkScalar fStrikeoutThickness; //!< strikeout thickness
SkScalar fStrikeoutPosition; //!< strikeout position relative to baseline
/** Returns true if SkFontMetrics has a valid underline thickness, and sets
thickness to that value. If the underline thickness is not valid,
return false, and ignore thickness.
@param thickness storage for underline width
@return true if font specifies underline width
*/
bool hasUnderlineThickness(SkScalar* thickness) const {
if (SkToBool(fFlags & kUnderlineThicknessIsValid_Flag)) {
*thickness = fUnderlineThickness;
return true;
}
return false;
}
/** Returns true if SkFontMetrics has a valid underline position, and sets
position to that value. If the underline position is not valid,
return false, and ignore position.
@param position storage for underline position
@return true if font specifies underline position
*/
bool hasUnderlinePosition(SkScalar* position) const {
if (SkToBool(fFlags & kUnderlinePositionIsValid_Flag)) {
*position = fUnderlinePosition;
return true;
}
return false;
}
/** Returns true if SkFontMetrics has a valid strikeout thickness, and sets
thickness to that value. If the underline thickness is not valid,
return false, and ignore thickness.
@param thickness storage for strikeout width
@return true if font specifies strikeout width
*/
bool hasStrikeoutThickness(SkScalar* thickness) const {
if (SkToBool(fFlags & kStrikeoutThicknessIsValid_Flag)) {
*thickness = fStrikeoutThickness;
return true;
}
return false;
}
/** Returns true if SkFontMetrics has a valid strikeout position, and sets
position to that value. If the underline position is not valid,
return false, and ignore position.
@param position storage for strikeout position
@return true if font specifies strikeout position
*/
bool hasStrikeoutPosition(SkScalar* position) const {
if (SkToBool(fFlags & kStrikeoutPositionIsValid_Flag)) {
*position = fStrikeoutPosition;
return true;
}
return false;
}
};
#endif

163
skia/include/core/SkFontMgr.h vendored Normal file
View File

@ -0,0 +1,163 @@
/*
* Copyright 2013 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkFontMgr_DEFINED
#define SkFontMgr_DEFINED
#include "SkFontArguments.h"
#include "SkFontStyle.h"
#include "SkRefCnt.h"
#include "SkTypes.h"
class SkData;
class SkFontData;
class SkStreamAsset;
class SkString;
class SkTypeface;
class SK_API SkFontStyleSet : public SkRefCnt {
public:
virtual int count() = 0;
virtual void getStyle(int index, SkFontStyle*, SkString* style) = 0;
virtual SkTypeface* createTypeface(int index) = 0;
virtual SkTypeface* matchStyle(const SkFontStyle& pattern) = 0;
static SkFontStyleSet* CreateEmpty();
protected:
SkTypeface* matchStyleCSS3(const SkFontStyle& pattern);
private:
typedef SkRefCnt INHERITED;
};
class SK_API SkFontMgr : public SkRefCnt {
public:
int countFamilies() const;
void getFamilyName(int index, SkString* familyName) const;
SkFontStyleSet* createStyleSet(int index) const;
/**
* The caller must call unref() on the returned object.
* Never returns NULL; will return an empty set if the name is not found.
*
* Passing nullptr as the parameter will return the default system family.
* Note that most systems don't have a default system family, so passing nullptr will often
* result in the empty set.
*
* It is possible that this will return a style set not accessible from
* createStyleSet(int) due to hidden or auto-activated fonts.
*/
SkFontStyleSet* matchFamily(const char familyName[]) const;
/**
* Find the closest matching typeface to the specified familyName and style
* and return a ref to it. The caller must call unref() on the returned
* object. Will return nullptr if no 'good' match is found.
*
* Passing |nullptr| as the parameter for |familyName| will return the
* default system font.
*
* It is possible that this will return a style set not accessible from
* createStyleSet(int) or matchFamily(const char[]) due to hidden or
* auto-activated fonts.
*/
SkTypeface* matchFamilyStyle(const char familyName[], const SkFontStyle&) const;
/**
* Use the system fallback to find a typeface for the given character.
* Note that bcp47 is a combination of ISO 639, 15924, and 3166-1 codes,
* so it is fine to just pass a ISO 639 here.
*
* Will return NULL if no family can be found for the character
* in the system fallback.
*
* Passing |nullptr| as the parameter for |familyName| will return the
* default system font.
*
* bcp47[0] is the least significant fallback, bcp47[bcp47Count-1] is the
* most significant. If no specified bcp47 codes match, any font with the
* requested character will be matched.
*/
SkTypeface* matchFamilyStyleCharacter(const char familyName[], const SkFontStyle&,
const char* bcp47[], int bcp47Count,
SkUnichar character) const;
SkTypeface* matchFaceStyle(const SkTypeface*, const SkFontStyle&) const;
/**
* Create a typeface for the specified data and TTC index (pass 0 for none)
* or NULL if the data is not recognized. The caller must call unref() on
* the returned object if it is not null.
*/
sk_sp<SkTypeface> makeFromData(sk_sp<SkData>, int ttcIndex = 0) const;
/**
* Create a typeface for the specified stream and TTC index
* (pass 0 for none) or NULL if the stream is not recognized. The caller
* must call unref() on the returned object if it is not null.
*/
sk_sp<SkTypeface> makeFromStream(std::unique_ptr<SkStreamAsset>, int ttcIndex = 0) const;
/* Experimental, API subject to change. */
sk_sp<SkTypeface> makeFromStream(std::unique_ptr<SkStreamAsset>, const SkFontArguments&) const;
/**
* Create a typeface from the specified font data.
* Will return NULL if the typeface could not be created.
* The caller must call unref() on the returned object if it is not null.
*/
sk_sp<SkTypeface> makeFromFontData(std::unique_ptr<SkFontData>) const;
/**
* Create a typeface for the specified fileName and TTC index
* (pass 0 for none) or NULL if the file is not found, or its contents are
* not recognized. The caller must call unref() on the returned object
* if it is not null.
*/
sk_sp<SkTypeface> makeFromFile(const char path[], int ttcIndex = 0) const;
sk_sp<SkTypeface> legacyMakeTypeface(const char familyName[], SkFontStyle style) const;
/** Return the default fontmgr. */
static sk_sp<SkFontMgr> RefDefault();
protected:
virtual int onCountFamilies() const = 0;
virtual void onGetFamilyName(int index, SkString* familyName) const = 0;
virtual SkFontStyleSet* onCreateStyleSet(int index)const = 0;
/** May return NULL if the name is not found. */
virtual SkFontStyleSet* onMatchFamily(const char familyName[]) const = 0;
virtual SkTypeface* onMatchFamilyStyle(const char familyName[],
const SkFontStyle&) const = 0;
virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], const SkFontStyle&,
const char* bcp47[], int bcp47Count,
SkUnichar character) const = 0;
virtual SkTypeface* onMatchFaceStyle(const SkTypeface*,
const SkFontStyle&) const = 0;
virtual sk_sp<SkTypeface> onMakeFromData(sk_sp<SkData>, int ttcIndex) const = 0;
virtual sk_sp<SkTypeface> onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset>,
int ttcIndex) const = 0;
virtual sk_sp<SkTypeface> onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset>,
const SkFontArguments&) const;
virtual sk_sp<SkTypeface> onMakeFromFontData(std::unique_ptr<SkFontData>) const;
virtual sk_sp<SkTypeface> onMakeFromFile(const char path[], int ttcIndex) const = 0;
virtual sk_sp<SkTypeface> onLegacyMakeTypeface(const char familyName[], SkFontStyle) const = 0;
private:
/** Implemented by porting layer to return the default factory. */
static sk_sp<SkFontMgr> Factory();
typedef SkRefCnt INHERITED;
};
#endif

38
skia/include/core/SkFontParameters.h vendored Normal file
View File

@ -0,0 +1,38 @@
/*
* Copyright 2018 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkFontParameters_DEFINED
#define SkFontParameters_DEFINED
#include "SkScalar.h"
#include "SkTypes.h"
struct SkFontParameters {
struct Variation {
// Parameters in a variation font axis.
struct Axis {
// Four character identifier of the font axis (weight, width, slant, italic...).
SkFourByteTag tag;
// Minimum value supported by this axis.
float min;
// Default value set by this axis.
float def;
// Maximum value supported by this axis. The maximum can equal the minimum.
float max;
// Return whether this axis is recommended to be remain hidden in user interfaces.
bool isHidden() const { return flags & HIDDEN; }
// Set this axis to be remain hidden in user interfaces.
void setHidden(bool hidden) { flags = hidden ? (flags | HIDDEN) : (flags & ~HIDDEN); }
private:
static constexpr uint16_t HIDDEN = 0x0001;
// Attributes for a font axis.
uint16_t flags;
};
};
};
#endif

80
skia/include/core/SkFontStyle.h vendored Normal file
View File

@ -0,0 +1,80 @@
/*
* Copyright 2013 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkFontStyle_DEFINED
#define SkFontStyle_DEFINED
#include "SkTypes.h"
class SK_API SkFontStyle {
public:
enum Weight {
kInvisible_Weight = 0,
kThin_Weight = 100,
kExtraLight_Weight = 200,
kLight_Weight = 300,
kNormal_Weight = 400,
kMedium_Weight = 500,
kSemiBold_Weight = 600,
kBold_Weight = 700,
kExtraBold_Weight = 800,
kBlack_Weight = 900,
kExtraBlack_Weight = 1000,
};
enum Width {
kUltraCondensed_Width = 1,
kExtraCondensed_Width = 2,
kCondensed_Width = 3,
kSemiCondensed_Width = 4,
kNormal_Width = 5,
kSemiExpanded_Width = 6,
kExpanded_Width = 7,
kExtraExpanded_Width = 8,
kUltraExpanded_Width = 9,
};
enum Slant {
kUpright_Slant,
kItalic_Slant,
kOblique_Slant,
};
constexpr SkFontStyle(int weight, int width, Slant slant) : fValue(
(SkTPin<int>(weight, kInvisible_Weight, kExtraBlack_Weight)) +
(SkTPin<int>(width, kUltraCondensed_Width, kUltraExpanded_Width) << 16) +
(SkTPin<int>(slant, kUpright_Slant, kOblique_Slant) << 24)
) { }
constexpr SkFontStyle() : SkFontStyle{kNormal_Weight, kNormal_Width, kUpright_Slant} { }
bool operator==(const SkFontStyle& rhs) const {
return fValue == rhs.fValue;
}
int weight() const { return fValue & 0xFFFF; }
int width() const { return (fValue >> 16) & 0xFF; }
Slant slant() const { return (Slant)((fValue >> 24) & 0xFF); }
static constexpr SkFontStyle Normal() {
return SkFontStyle(kNormal_Weight, kNormal_Width, kUpright_Slant);
}
static constexpr SkFontStyle Bold() {
return SkFontStyle(kBold_Weight, kNormal_Width, kUpright_Slant);
}
static constexpr SkFontStyle Italic() {
return SkFontStyle(kNormal_Weight, kNormal_Width, kItalic_Slant );
}
static constexpr SkFontStyle BoldItalic() {
return SkFontStyle(kBold_Weight, kNormal_Width, kItalic_Slant );
}
private:
uint32_t fValue;
};
#endif

49
skia/include/core/SkFontTypes.h vendored Normal file
View File

@ -0,0 +1,49 @@
/*
* Copyright 2018 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkFontTypes_DEFINED
#define SkFontTypes_DEFINED
#include "SkScalar.h"
#include "SkTypeface.h"
// TODO: add to clients, and then remove from here.
#define SK_SUPPORT_LEGACY_TEXTENCODINGENUM
#ifdef SK_SUPPORT_LEGACY_TEXTENCODINGENUM
enum SkTextEncoding : uint8_t {
kUTF8_SkTextEncoding,
kUTF16_SkTextEncoding,
kUTF32_SkTextEncoding,
kGlyphID_SkTextEncoding,
};
#else
enum class SkTextEncoding {
kUTF8,
kUTF16,
kUTF32,
kGlyphID,
};
#define kUTF8_SkTextEncoding SkTextEncoding::kUTF8
#define kUTF16_SkTextEncoding SkTextEncoding::kUTF16
#define kUTF32_SkTextEncoding SkTextEncoding::kUTF32
#define kGlyphID_SkTextEncoding SkTextEncoding::kGlyphID
#endif
enum class SkFontHinting {
kNone, //!< glyph outlines unchanged
kSlight, //!< minimal modification to improve constrast
kNormal, //!< glyph outlines modified to improve constrast
kFull, //!< modifies glyph outlines for maximum constrast
};
#define kNo_SkFontHinting SkFontHinting::kNone
#define kSlight_SkFontHinting SkFontHinting::kSlight
#define kNormal_SkFontHinting SkFontHinting::kNormal
#define kFull_SkFontHinting SkFontHinting::kFull
#endif

185
skia/include/core/SkGraphics.h vendored Normal file
View File

@ -0,0 +1,185 @@
/*
* Copyright 2006 The Android Open Source Project
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkGraphics_DEFINED
#define SkGraphics_DEFINED
#include "SkRefCnt.h"
class SkData;
class SkImageGenerator;
class SkTraceMemoryDump;
class SK_API SkGraphics {
public:
/**
* Call this at process initialization time if your environment does not
* permit static global initializers that execute code.
* Init() is thread-safe and idempotent.
*/
static void Init();
// We're in the middle of cleaning this up.
static void Term() {}
/**
* Return the version numbers for the library. If the parameter is not
* null, it is set to the version number.
*/
static void GetVersion(int32_t* major, int32_t* minor, int32_t* patch);
/**
* Return the max number of bytes that should be used by the font cache.
* If the cache needs to allocate more, it will purge previous entries.
* This max can be changed by calling SetFontCacheLimit().
*/
static size_t GetFontCacheLimit();
/**
* Specify the max number of bytes that should be used by the font cache.
* If the cache needs to allocate more, it will purge previous entries.
*
* This function returns the previous setting, as if GetFontCacheLimit()
* had be called before the new limit was set.
*/
static size_t SetFontCacheLimit(size_t bytes);
/**
* Return the number of bytes currently used by the font cache.
*/
static size_t GetFontCacheUsed();
/**
* Return the number of entries in the font cache.
* A cache "entry" is associated with each typeface + pointSize + matrix.
*/
static int GetFontCacheCountUsed();
/**
* Return the current limit to the number of entries in the font cache.
* A cache "entry" is associated with each typeface + pointSize + matrix.
*/
static int GetFontCacheCountLimit();
/**
* Set the limit to the number of entries in the font cache, and return
* the previous value. If this new value is lower than the previous,
* it will automatically try to purge entries to meet the new limit.
*/
static int SetFontCacheCountLimit(int count);
/*
* Returns the maximum point size for text that may be cached.
*
* Sizes above this will be drawn directly from the font's outline.
* Setting this to a large value may speed up drawing larger text (repeatedly),
* but could cause the cache to purge other sizes more often.
*
* This value is a hint to the font engine, and the actual limit may be different due to
* implementation specific details.
*/
static int GetFontCachePointSizeLimit();
/*
* Set the maximum point size for text that may be cached, returning the previous value.
*
* Sizes above this will be drawn directly from the font's outline.
* Setting this to a large value may speed up drawing larger text (repeatedly),
* but could cause the cache to purge other sizes more often.
*
* This value is a hint to the font engine, and the actual limit may be different due to
* implementation specific details.
*/
static int SetFontCachePointSizeLimit(int maxPointSize);
/**
* For debugging purposes, this will attempt to purge the font cache. It
* does not change the limit, but will cause subsequent font measures and
* draws to be recreated, since they will no longer be in the cache.
*/
static void PurgeFontCache();
/**
* Scaling bitmaps with the kHigh_SkFilterQuality setting is
* expensive, so the result is saved in the global Scaled Image
* Cache.
*
* This function returns the memory usage of the Scaled Image Cache.
*/
static size_t GetResourceCacheTotalBytesUsed();
/**
* These functions get/set the memory usage limit for the resource cache, used for temporary
* bitmaps and other resources. Entries are purged from the cache when the memory useage
* exceeds this limit.
*/
static size_t GetResourceCacheTotalByteLimit();
static size_t SetResourceCacheTotalByteLimit(size_t newLimit);
/**
* For debugging purposes, this will attempt to purge the resource cache. It
* does not change the limit.
*/
static void PurgeResourceCache();
/**
* When the cachable entry is very lage (e.g. a large scaled bitmap), adding it to the cache
* can cause most/all of the existing entries to be purged. To avoid the, the client can set
* a limit for a single allocation. If a cacheable entry would have been cached, but its size
* exceeds this limit, then we do not attempt to cache it at all.
*
* Zero is the default value, meaning we always attempt to cache entries.
*/
static size_t GetResourceCacheSingleAllocationByteLimit();
static size_t SetResourceCacheSingleAllocationByteLimit(size_t newLimit);
/**
* Dumps memory usage of caches using the SkTraceMemoryDump interface. See SkTraceMemoryDump
* for usage of this method.
*/
static void DumpMemoryStatistics(SkTraceMemoryDump* dump);
/**
* Free as much globally cached memory as possible. This will purge all private caches in Skia,
* including font and image caches.
*
* If there are caches associated with GPU context, those will not be affected by this call.
*/
static void PurgeAllCaches();
/**
* Applications with command line options may pass optional state, such
* as cache sizes, here, for instance:
* font-cache-limit=12345678
*
* The flags format is name=value[;name=value...] with no spaces.
* This format is subject to change.
*/
static void SetFlags(const char* flags);
typedef std::unique_ptr<SkImageGenerator>
(*ImageGeneratorFromEncodedDataFactory)(sk_sp<SkData>);
/**
* To instantiate images from encoded data, first looks at this runtime function-ptr. If it
* exists, it is called to create an SkImageGenerator from SkData. If there is no function-ptr
* or there is, but it returns NULL, then skia will call its internal default implementation.
*
* Returns the previous factory (which could be NULL).
*/
static ImageGeneratorFromEncodedDataFactory
SetImageGeneratorFromEncodedDataFactory(ImageGeneratorFromEncodedDataFactory);
};
class SkAutoGraphics {
public:
SkAutoGraphics() {
SkGraphics::Init();
}
};
#endif

23
skia/include/core/SkICC.h vendored Normal file
View File

@ -0,0 +1,23 @@
/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkICC_DEFINED
#define SkICC_DEFINED
#include "SkData.h"
#include "SkMatrix44.h"
#include "SkRefCnt.h"
struct SkColorSpaceTransferFn;
SK_API sk_sp<SkData> SkWriteICCProfile(const SkColorSpaceTransferFn&, const float toXYZD50[9]);
namespace SkICC {
SK_API sk_sp<SkData> WriteToICC(const SkColorSpaceTransferFn&, const SkMatrix44&);
}
#endif//SkICC_DEFINED

1026
skia/include/core/SkImage.h vendored Normal file

File diff suppressed because it is too large Load Diff

68
skia/include/core/SkImageEncoder.h vendored Normal file
View File

@ -0,0 +1,68 @@
/*
* 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 SkImageEncoder_DEFINED
#define SkImageEncoder_DEFINED
#include "SkBitmap.h"
#include "SkData.h"
#include "SkEncodedImageFormat.h"
#include "SkStream.h"
/**
* Encode SkPixmap in the given binary image format.
*
* @param dst results are written to this stream.
* @param src source pixels.
* @param format image format, not all formats are supported.
* @param quality range from 0-100, this is supported by jpeg and webp.
* higher values correspond to improved visual quality, but less compression.
*
* @return false iff input is bad or format is unsupported.
*
* Will always return false if Skia is compiled without image
* encoders.
*
* Note that webp encodes will use webp lossy compression.
*
* For examples of encoding an image to a file or to a block of memory,
* see tools/sk_tool_utils.h.
*/
SK_API bool SkEncodeImage(SkWStream* dst, const SkPixmap& src,
SkEncodedImageFormat format, int quality);
/**
* The following helper function wraps SkEncodeImage().
*/
inline bool SkEncodeImage(SkWStream* dst, const SkBitmap& src, SkEncodedImageFormat f, int q) {
SkPixmap pixmap;
return src.peekPixels(&pixmap) && SkEncodeImage(dst, pixmap, f, q);
}
/**
* Encode SkPixmap in the given binary image format.
*
* @param src source pixels.
* @param format image format, not all formats are supported.
* @param quality range from 0-100, this is supported by jpeg and webp.
* higher values correspond to improved visual quality, but less compression.
*
* @return encoded data or nullptr if input is bad or format is unsupported.
*
* Will always return nullptr if Skia is compiled without image
* encoders.
*
* Note that webp encodes will use webp lossy compression.
*/
SK_API sk_sp<SkData> SkEncodePixmap(const SkPixmap& src, SkEncodedImageFormat format, int quality);
/**
* Helper that extracts the pixmap from the bitmap, and then calls SkEncodePixmap()
*/
SK_API sk_sp<SkData> SkEncodeBitmap(const SkBitmap& src, SkEncodedImageFormat format, int quality);
#endif // SkImageEncoder_DEFINED

479
skia/include/core/SkImageFilter.h vendored Normal file
View File

@ -0,0 +1,479 @@
/*
* 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 "../private/SkTArray.h"
#include "../private/SkTemplates.h"
#include "../private/SkMutex.h"
#include "SkColorSpace.h"
#include "SkFilterQuality.h"
#include "SkFlattenable.h"
#include "SkImageInfo.h"
#include "SkMatrix.h"
#include "SkRect.h"
class GrContext;
class GrFragmentProcessor;
class SkColorFilter;
class SkColorSpaceXformer;
struct SkIPoint;
class SkSpecialImage;
class SkImageFilterCache;
struct SkImageFilterCacheKey;
/**
* 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).
*/
class SK_API SkImageFilter : public SkFlattenable {
public:
// Extra information about the output of a filter DAG. For now, this is just the color space
// (of the original requesting device). This is used when constructing intermediate rendering
// surfaces, so that we ensure we land in a surface that's similar/compatible to the final
// consumer of the DAG's output.
class OutputProperties {
public:
explicit OutputProperties(SkColorType colorType, SkColorSpace* colorSpace)
: fColorType(colorType), fColorSpace(colorSpace) {}
SkColorType colorType() const { return fColorType; }
SkColorSpace* colorSpace() const { return fColorSpace; }
private:
SkColorType fColorType;
// This will be a pointer to the device's color space, and our lifetime is bounded by
// the device, so we can store a bare pointer.
SkColorSpace* fColorSpace;
};
class Context {
public:
Context(const SkMatrix& ctm, const SkIRect& clipBounds, SkImageFilterCache* cache,
const OutputProperties& outputProperties)
: fCTM(ctm)
, fClipBounds(clipBounds)
, fCache(cache)
, fOutputProperties(outputProperties)
{}
const SkMatrix& ctm() const { return fCTM; }
const SkIRect& clipBounds() const { return fClipBounds; }
SkImageFilterCache* cache() const { return fCache; }
const OutputProperties& outputProperties() const { return fOutputProperties; }
/**
* Since a context can be build directly, its constructor has no chance to
* "return null" if it's given invalid or unsupported inputs. Call this to
* know of the the context can be used.
*
* The SkImageFilterCache Key, for example, requires a finite ctm (no infinities
* or NaN), so that test is part of isValid.
*/
bool isValid() const { return fCTM.isFinite(); }
private:
SkMatrix fCTM;
SkIRect fClipBounds;
SkImageFilterCache* fCache;
OutputProperties fOutputProperties;
};
class CropRect {
public:
enum CropEdge {
kHasLeft_CropEdge = 0x01,
kHasTop_CropEdge = 0x02,
kHasWidth_CropEdge = 0x04,
kHasHeight_CropEdge = 0x08,
kHasAll_CropEdge = 0x0F,
};
CropRect() {}
explicit CropRect(const SkRect& rect, uint32_t flags = kHasAll_CropEdge)
: fRect(rect), fFlags(flags) {}
uint32_t flags() const { return fFlags; }
const SkRect& rect() const { return fRect; }
/**
* Apply this cropRect to the imageBounds. If a given edge of the cropRect is not
* set, then the corresponding edge from imageBounds will be used. If "embiggen"
* is true, the crop rect is allowed to enlarge the size of the rect, otherwise
* it may only reduce the rect. Filters that can affect transparent black should
* pass "true", while all other filters should pass "false".
*
* Note: imageBounds is in "device" space, as the output cropped rectangle will be,
* so the matrix is ignored for those. It is only applied the croprect's bounds.
*/
void applyTo(const SkIRect& imageBounds, const SkMatrix& matrix, bool embiggen,
SkIRect* cropped) const;
private:
SkRect fRect;
uint32_t fFlags;
};
enum TileUsage {
kPossible_TileUsage, //!< the created device may be drawn tiled
kNever_TileUsage, //!< the created device will never be drawn tiled
};
/**
* Request a new filtered image to be created from the src image.
*
* The context contains the environment in which the filter is occurring.
* It includes the clip bounds, CTM and cache.
*
* Offset is the amount to translate the resulting image relative to the
* src when it is drawn. This is an out-param.
*
* If the result image cannot be created, or the result would be
* transparent black, return null, in which case the offset parameter
* should be ignored by the caller.
*
* TODO: Right now the imagefilters sometimes return empty result bitmaps/
* specialimages. That doesn't seem quite right.
*/
sk_sp<SkSpecialImage> filterImage(SkSpecialImage* src, const Context& context,
SkIPoint* offset) const;
enum MapDirection {
kForward_MapDirection,
kReverse_MapDirection,
};
/**
* Map a device-space rect recursively forward or backward through the
* filter DAG. kForward_MapDirection is used to determine which pixels of
* the destination canvas a source image rect would touch after filtering.
* kReverse_MapDirection is used to determine which rect of the source
* image would be required to fill the given rect (typically, clip bounds).
* Used for clipping and temp-buffer allocations, so the result need not
* be exact, but should never be smaller than the real answer. The default
* implementation recursively unions all input bounds, or returns the
* source rect if no inputs.
*
* In kReverse mode, 'inputRect' is the device-space bounds of the input pixels. In kForward
* mode it should always be null. If 'inputRect' is null in kReverse mode the resulting
* answer may be incorrect.
*/
SkIRect filterBounds(const SkIRect& src, const SkMatrix& ctm,
MapDirection, const SkIRect* inputRect = nullptr) const;
#if SK_SUPPORT_GPU
static sk_sp<SkSpecialImage> DrawWithFP(GrContext* context,
std::unique_ptr<GrFragmentProcessor> fp,
const SkIRect& bounds,
const OutputProperties& outputProperties);
#endif
/**
* Returns whether this image filter is a color filter and puts the color filter into the
* "filterPtr" parameter if it can. Does nothing otherwise.
* If this returns false, then the filterPtr is unchanged.
* If this returns true, then if filterPtr is not null, it must be set to a ref'd colorfitler
* (i.e. it may not be set to NULL).
*/
bool isColorFilterNode(SkColorFilter** filterPtr) const {
return this->onIsColorFilterNode(filterPtr);
}
// DEPRECATED : use isColorFilterNode() instead
bool asColorFilter(SkColorFilter** filterPtr) const {
return this->isColorFilterNode(filterPtr);
}
void removeKey(const SkImageFilterCacheKey& key) const;
/**
* Returns true (and optionally returns a ref'd filter) if this imagefilter can be completely
* replaced by the returned colorfilter. i.e. the two effects will affect drawing in the
* same way.
*/
bool asAColorFilter(SkColorFilter** filterPtr) const;
/**
* Returns the number of inputs this filter will accept (some inputs can
* be NULL).
*/
int countInputs() const { return fInputs.count(); }
/**
* Returns the input filter at a given index, or NULL if no input is
* connected. The indices used are filter-specific.
*/
SkImageFilter* getInput(int i) const {
SkASSERT(i < fInputs.count());
return fInputs[i].get();
}
/**
* Returns whether any edges of the crop rect have been set. The crop
* rect is set at construction time, and determines which pixels from the
* input image will be processed, and which pixels in the output image will be allowed.
* The size of the crop rect should be
* used as the size of the destination image. The origin of this rect
* should be used to offset access to the input images, and should also
* be added to the "offset" parameter in onFilterImage.
*/
bool cropRectIsSet() const { return fCropRect.flags() != 0x0; }
CropRect getCropRect() const { return fCropRect; }
// Default impl returns union of all input bounds.
virtual SkRect computeFastBounds(const SkRect& bounds) const;
// Can this filter DAG compute the resulting bounds of an object-space rectangle?
bool canComputeFastBounds() const;
/**
* If this filter can be represented by another filter + a localMatrix, return that filter,
* else return null.
*/
sk_sp<SkImageFilter> makeWithLocalMatrix(const SkMatrix& matrix) const;
/**
* ImageFilters can natively handle scaling and translate components in the CTM. Only some of
* them can handle affine (or more complex) matrices. This call returns true iff the filter
* and all of its (non-null) inputs can handle these more complex matrices.
*/
bool canHandleComplexCTM() const;
/**
* Return an imagefilter which transforms its input by the given matrix.
*/
static sk_sp<SkImageFilter> MakeMatrixFilter(const SkMatrix& matrix,
SkFilterQuality quality,
sk_sp<SkImageFilter> input);
static void RegisterFlattenables();
static SkFlattenable::Type GetFlattenableType() {
return kSkImageFilter_Type;
}
SkFlattenable::Type getFlattenableType() const override {
return kSkImageFilter_Type;
}
static sk_sp<SkImageFilter> Deserialize(const void* data, size_t size,
const SkDeserialProcs* procs = nullptr) {
return sk_sp<SkImageFilter>(static_cast<SkImageFilter*>(
SkFlattenable::Deserialize(
kSkImageFilter_Type, data, size, procs).release()));
}
protected:
class Common {
public:
/**
* Attempt to unflatten the cropRect and the expected number of input filters.
* If any number of input filters is valid, pass -1.
* If this fails (i.e. corrupt buffer or contents) then return false and common will
* be left uninitialized.
* If this returns true, then inputCount() is the number of found input filters, each
* of which may be NULL or a valid imagefilter.
*/
bool unflatten(SkReadBuffer&, int expectedInputs);
const CropRect& cropRect() const { return fCropRect; }
int inputCount() const { return fInputs.count(); }
sk_sp<SkImageFilter>* inputs() { return fInputs.begin(); }
sk_sp<SkImageFilter> getInput(int index) { return fInputs[index]; }
private:
CropRect fCropRect;
// most filters accept at most 2 input-filters
SkSTArray<2, sk_sp<SkImageFilter>, true> fInputs;
};
SkImageFilter(sk_sp<SkImageFilter> const* inputs, int inputCount, const CropRect* cropRect);
~SkImageFilter() override;
/**
* Constructs a new SkImageFilter read from an SkReadBuffer object.
*
* @param inputCount The exact number of inputs expected for this SkImageFilter object.
* -1 can be used if the filter accepts any number of inputs.
* @param rb SkReadBuffer object from which the SkImageFilter is read.
*/
explicit SkImageFilter(int inputCount, SkReadBuffer& rb);
void flatten(SkWriteBuffer&) const override;
const CropRect* getCropRectIfSet() const {
return this->cropRectIsSet() ? &fCropRect : nullptr;
}
/**
* This is the virtual which should be overridden by the derived class
* to perform image filtering.
*
* src is the original primitive bitmap. If the filter has a connected
* input, it should recurse on that input and use that in place of src.
*
* 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. This is an out-param.
*
* If the result image cannot be created (either because of error or if, say, the result
* is entirely clipped out), this should return nullptr.
* Callers that affect transparent black should explicitly handle nullptr
* results and press on. In the error case this behavior will produce a better result
* than nothing and is necessary for the clipped out case.
* If the return value is nullptr then offset should be ignored.
*/
virtual sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* src, const Context&,
SkIPoint* offset) const = 0;
/**
* This function recurses into its inputs with the given rect (first
* argument), calls filterBounds() with the given map direction on each,
* and returns the union of those results. If a derived class has special
* recursion requirements (e.g., it has an input which does not participate
* in bounds computation), it can be overridden here.
* In kReverse mode, 'inputRect' is the device-space bounds of the input pixels. In kForward
* mode it should always be null. If 'inputRect' is null in kReverse mode the resulting
* answer may be incorrect.
*
* Note that this function is *not* responsible for mapping the rect for
* this node's filter bounds requirements (i.e., calling
* onFilterNodeBounds()); that is handled by filterBounds().
*/
virtual SkIRect onFilterBounds(const SkIRect&, const SkMatrix& ctm,
MapDirection, const SkIRect* inputRect) const;
/**
* Performs a forwards or reverse mapping of the given rect to accommodate
* this filter's margin requirements. kForward_MapDirection is used to
* determine the destination pixels which would be touched by filtering
* the given source rect (e.g., given source bitmap bounds,
* determine the optimal bounds of the filtered offscreen bitmap).
* kReverse_MapDirection is used to determine which pixels of the
* input(s) would be required to fill the given destination rect
* (e.g., clip bounds). NOTE: these operations may not be the
* inverse of the other. For example, blurring expands the given rect
* in both forward and reverse directions. Unlike
* onFilterBounds(), this function is non-recursive.
* In kReverse mode, 'inputRect' will be the device space bounds of the input pixels. In
* kForward mode, 'inputRect' should always be null. If 'inputRect' is null in kReverse mode
* the resulting answer may be incorrect.
*/
virtual SkIRect onFilterNodeBounds(const SkIRect&, const SkMatrix& ctm,
MapDirection, const SkIRect* inputRect) const;
// Helper function which invokes filter processing on the input at the
// specified "index". If the input is null, it returns "src" and leaves
// "offset" untouched. If the input is non-null, it
// calls filterImage() on that input, and returns the result.
sk_sp<SkSpecialImage> filterInput(int index,
SkSpecialImage* src,
const Context&,
SkIPoint* offset) const;
/**
* Return true (and return a ref'd colorfilter) if this node in the DAG is just a
* colorfilter w/o CropRect constraints.
*/
virtual bool onIsColorFilterNode(SkColorFilter** /*filterPtr*/) const {
return false;
}
/**
* Override this to describe the behavior of your subclass - as a leaf node. The caller will
* take care of calling your inputs (and return false if any of them could not handle it).
*/
virtual bool onCanHandleComplexCTM() const { return false; }
/** Given a "srcBounds" rect, computes destination bounds for this filter.
* "dstBounds" are computed by transforming the crop rect by the context's
* CTM, applying it to the initial bounds, and intersecting the result with
* the context's clip bounds. "srcBounds" (if non-null) are computed by
* intersecting the initial bounds with "dstBounds", to ensure that we never
* sample outside of the crop rect (this restriction may be relaxed in the
* future).
*/
bool applyCropRect(const Context&, const SkIRect& srcBounds, SkIRect* dstBounds) const;
/** A variant of the above call which takes the original source bitmap and
* source offset. If the resulting crop rect is not entirely contained by
* the source bitmap's bounds, it creates a new bitmap in "result" and
* pads the edges with transparent black. In that case, the srcOffset is
* modified to be the same as the bounds, since no further adjustment is
* needed by the caller. This version should only be used by filters
* which are not capable of processing a smaller source bitmap into a
* larger destination.
*/
sk_sp<SkSpecialImage> applyCropRectAndPad(const Context&, SkSpecialImage* src,
SkIPoint* srcOffset, SkIRect* bounds) const;
/**
* Creates a modified Context for use when recursing up the image filter DAG.
* The clip bounds are adjusted to accommodate any margins that this
* filter requires by calling this node's
* onFilterNodeBounds(..., kReverse_MapDirection).
*/
Context mapContext(const Context& ctx) const;
#if SK_SUPPORT_GPU
/**
* Returns a version of the passed-in image (possibly the original), that is in a colorspace
* with the same gamut as the one from the OutputProperties. This allows filters that do many
* texture samples to guarantee that any color space conversion has happened before running.
*/
static sk_sp<SkSpecialImage> ImageToColorSpace(SkSpecialImage* src, const OutputProperties&);
#endif
/**
* Returns an image filter transformed into a new color space via the |xformer|.
*/
sk_sp<SkImageFilter> makeColorSpace(SkColorSpaceXformer* xformer) const {
return this->onMakeColorSpace(xformer);
}
virtual sk_sp<SkImageFilter> onMakeColorSpace(SkColorSpaceXformer*) const = 0;
sk_sp<SkImageFilter> refMe() const {
return sk_ref_sp(const_cast<SkImageFilter*>(this));
}
// If 'srcBounds' will sample outside the border of 'originalSrcBounds' (i.e., the sample
// will wrap around to the other side) we must preserve the far side of the src along that
// axis (e.g., if we will sample beyond the left edge of the src, the right side must be
// preserved for the repeat sampling to work).
static SkIRect DetermineRepeatedSrcBound(const SkIRect& srcBounds,
const SkIVector& filterOffset,
const SkISize& filterSize,
const SkIRect& originalSrcBounds);
private:
// For makeColorSpace().
friend class SkColorSpaceXformer;
friend class SkGraphics;
static void PurgeCache();
void init(sk_sp<SkImageFilter> const* inputs, int inputCount, const CropRect* cropRect);
bool usesSrcInput() const { return fUsesSrcInput; }
virtual bool affectsTransparentBlack() const { return false; }
SkAutoSTArray<2, sk_sp<SkImageFilter>> fInputs;
bool fUsesSrcInput;
CropRect fCropRect;
uint32_t fUniqueID; // Globally unique
typedef SkFlattenable INHERITED;
};
#endif

207
skia/include/core/SkImageGenerator.h vendored Normal file
View File

@ -0,0 +1,207 @@
/*
* Copyright 2013 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkImageGenerator_DEFINED
#define SkImageGenerator_DEFINED
#include "SkBitmap.h"
#include "SkColor.h"
#include "SkImage.h"
#include "SkImageInfo.h"
#include "SkYUVAIndex.h"
#include "SkYUVASizeInfo.h"
class GrContext;
class GrContextThreadSafeProxy;
class GrTextureProxy;
class GrSamplerState;
class SkBitmap;
class SkData;
class SkMatrix;
class SkPaint;
class SkPicture;
class SK_API SkImageGenerator {
public:
/**
* The PixelRef which takes ownership of this SkImageGenerator
* will call the image generator's destructor.
*/
virtual ~SkImageGenerator() { }
uint32_t uniqueID() const { return fUniqueID; }
/**
* Return a ref to the encoded (i.e. compressed) representation
* of this data.
*
* If non-NULL is returned, the caller is responsible for calling
* unref() on the data when it is finished.
*/
sk_sp<SkData> refEncodedData() {
return this->onRefEncodedData();
}
/**
* Return the ImageInfo associated with this generator.
*/
const SkImageInfo& getInfo() const { return fInfo; }
/**
* Can this generator be used to produce images that will be drawable to the specified context
* (or to CPU, if context is nullptr)?
*/
bool isValid(GrContext* context) const {
return this->onIsValid(context);
}
/**
* Decode into the given pixels, a block of memory of size at
* least (info.fHeight - 1) * rowBytes + (info.fWidth *
* bytesPerPixel)
*
* Repeated calls to this function should give the same results,
* allowing the PixelRef to be immutable.
*
* @param info A description of the format
* expected by the caller. This can simply be identical
* to the info returned by getInfo().
*
* This contract also allows the caller to specify
* different output-configs, which the implementation can
* decide to support or not.
*
* A size that does not match getInfo() implies a request
* to scale. If the generator cannot perform this scale,
* it will return false.
*
* @return true on success.
*/
bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes);
/**
* If decoding to YUV is supported, this returns true. Otherwise, this
* returns false and does not modify any of the parameters.
*
* @param sizeInfo Output parameter indicating the sizes and required
* allocation widths of the Y, U, V, and A planes.
* @param yuvaIndices How the YUVA planes are organized/used
* @param colorSpace Output parameter.
*/
bool queryYUVA8(SkYUVASizeInfo* sizeInfo,
SkYUVAIndex yuvaIndices[SkYUVAIndex::kIndexCount],
SkYUVColorSpace* colorSpace) const;
/**
* Returns true on success and false on failure.
* This always attempts to perform a full decode. If the client only
* wants size, it should call queryYUVA8().
*
* @param sizeInfo Needs to exactly match the values returned by the
* query, except the WidthBytes may be larger than the
* recommendation (but not smaller).
* @param yuvaIndices Needs to exactly match the values returned by the query.
* @param planes Memory for the Y, U, V, and A planes. Note that, depending on the
* settings in yuvaIndices, anywhere from 1..4 planes could be returned.
*/
bool getYUVA8Planes(const SkYUVASizeInfo& sizeInfo,
const SkYUVAIndex yuvaIndices[SkYUVAIndex::kIndexCount],
void* planes[]);
#if SK_SUPPORT_GPU
/**
* If the generator can natively/efficiently return its pixels as a GPU image (backed by a
* texture) this will return that image. If not, this will return NULL.
*
* This routine also supports retrieving only a subset of the pixels. That subset is specified
* by the following rectangle:
*
* subset = SkIRect::MakeXYWH(origin.x(), origin.y(), info.width(), info.height())
*
* If subset is not contained inside the generator's bounds, this returns false.
*
* whole = SkIRect::MakeWH(getInfo().width(), getInfo().height())
* if (!whole.contains(subset)) {
* return false;
* }
*
* Regarding the GrContext parameter:
*
* It must be non-NULL. The generator should only succeed if:
* - its internal context is the same
* - it can somehow convert its texture into one that is valid for the provided context.
*
* If the willNeedMipMaps flag is true, the generator should try to create a TextureProxy that
* at least has the mip levels allocated and the base layer filled in. If this is not possible,
* the generator is allowed to return a non mipped proxy, but this will have some additional
* overhead in later allocating mips and copying of the base layer.
*/
sk_sp<GrTextureProxy> generateTexture(GrContext*, const SkImageInfo& info,
const SkIPoint& origin,
bool willNeedMipMaps);
#endif
/**
* If the default image decoder system can interpret the specified (encoded) data, then
* this returns a new ImageGenerator for it. Otherwise this returns NULL. Either way
* the caller is still responsible for managing their ownership of the data.
*/
static std::unique_ptr<SkImageGenerator> MakeFromEncoded(sk_sp<SkData>);
/** Return a new image generator backed by the specified picture. If the size is empty or
* the picture is NULL, this returns NULL.
* The optional matrix and paint arguments are passed to drawPicture() at rasterization
* time.
*/
static std::unique_ptr<SkImageGenerator> MakeFromPicture(const SkISize&, sk_sp<SkPicture>,
const SkMatrix*, const SkPaint*,
SkImage::BitDepth,
sk_sp<SkColorSpace>);
protected:
static constexpr int kNeedNewImageUniqueID = 0;
SkImageGenerator(const SkImageInfo& info, uint32_t uniqueId = kNeedNewImageUniqueID);
virtual sk_sp<SkData> onRefEncodedData() { return nullptr; }
struct Options {};
virtual bool onGetPixels(const SkImageInfo&, void*, size_t, const Options&) { return false; }
virtual bool onIsValid(GrContext*) const { return true; }
virtual bool onQueryYUVA8(SkYUVASizeInfo*, SkYUVAIndex[SkYUVAIndex::kIndexCount],
SkYUVColorSpace*) const { return false; }
virtual bool onGetYUVA8Planes(const SkYUVASizeInfo&, const SkYUVAIndex[SkYUVAIndex::kIndexCount],
void*[4] /*planes*/) { return false; }
#if SK_SUPPORT_GPU
enum class TexGenType {
kNone, //image generator does not implement onGenerateTexture
kCheap, //onGenerateTexture is implemented and it is fast (does not render offscreen)
kExpensive, //onGenerateTexture is implemented and it is relatively slow
};
virtual TexGenType onCanGenerateTexture() const { return TexGenType::kNone; }
virtual sk_sp<GrTextureProxy> onGenerateTexture(GrContext*, const SkImageInfo&, const SkIPoint&,
bool willNeedMipMaps); // returns nullptr
#endif
private:
const SkImageInfo fInfo;
const uint32_t fUniqueID;
friend class SkImage_Lazy;
// This is our default impl, which may be different on different platforms.
// It is called from NewFromEncoded() after it has checked for any runtime factory.
// The SkData will never be NULL, as that will have been checked by NewFromEncoded.
static std::unique_ptr<SkImageGenerator> MakeFromEncodedImpl(sk_sp<SkData>);
SkImageGenerator(SkImageGenerator&&) = delete;
SkImageGenerator(const SkImageGenerator&) = delete;
SkImageGenerator& operator=(SkImageGenerator&&) = delete;
SkImageGenerator& operator=(const SkImageGenerator&) = delete;
};
#endif // SkImageGenerator_DEFINED

623
skia/include/core/SkImageInfo.h vendored Normal file
View File

@ -0,0 +1,623 @@
/*
* Copyright 2013 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/* Generated by tools/bookmaker from include/core/SkImageInfo.h and docs/SkImageInfo_Reference.bmh
on 2018-07-13 08:15:11. Additional documentation and examples can be found at:
https://skia.org/user/api/SkImageInfo_Reference
You may edit either file directly. Structural changes to public interfaces require
editing both files. After editing docs/SkImageInfo_Reference.bmh, run:
bookmaker -b docs -i include/core/SkImageInfo.h -p
to create an updated version of this file.
*/
#ifndef SkImageInfo_DEFINED
#define SkImageInfo_DEFINED
#include "SkColorSpace.h"
#include "SkMath.h"
#include "SkRect.h"
#include "SkSize.h"
#include "../private/SkTFitsIn.h"
#include "../private/SkTo.h"
class SkReadBuffer;
class SkWriteBuffer;
/** \enum SkImageInfo::SkAlphaType
Describes how to interpret the alpha component of a pixel. A pixel may
be opaque, or alpha, describing multiple levels of transparency.
In simple blending, alpha weights the draw color and the destination
color to create a new color. If alpha describes a weight from zero to one:
new color = draw color * alpha + destination color * (1 - alpha)
In practice alpha is encoded in two or more bits, where 1.0 equals all bits set.
RGB may have alpha included in each component value; the stored
value is the original RGB multiplied by alpha. Premultiplied color
components improve performance.
*/
enum SkAlphaType {
kUnknown_SkAlphaType, //!< uninitialized
kOpaque_SkAlphaType, //!< pixel is opaque
kPremul_SkAlphaType, //!< pixel components are premultiplied by alpha
kUnpremul_SkAlphaType, //!< pixel components are independent of alpha
kLastEnum_SkAlphaType = kUnpremul_SkAlphaType, //!< last valid value
};
/** Returns true if SkAlphaType equals kOpaque_SkAlphaType. kOpaque_SkAlphaType is a
hint that the SkColorType is opaque, or that all alpha values are set to
their 1.0 equivalent. If SkAlphaType is kOpaque_SkAlphaType, and SkColorType is not
opaque, then the result of drawing any pixel with a alpha value less than
1.0 is undefined.
@param at one of:
kUnknown_SkAlphaType, kOpaque_SkAlphaType, kPremul_SkAlphaType,
kUnpremul_SkAlphaType
@return true if at equals kOpaque_SkAlphaType
*/
static inline bool SkAlphaTypeIsOpaque(SkAlphaType at) {
return kOpaque_SkAlphaType == at;
}
///////////////////////////////////////////////////////////////////////////////
/** Temporary macro that allows us to add new color types without breaking Chrome compile. */
#define SK_EXTENDED_COLOR_TYPES
/** \enum SkImageInfo::SkColorType
Describes how pixel bits encode color. A pixel may be an alpha mask, a
grayscale, RGB, or ARGB.
kN32_SkColorType selects the native 32-bit ARGB format. On little endian
processors, pixels containing 8-bit ARGB components pack into 32-bit
kBGRA_8888_SkColorType. On big endian processors, pixels pack into 32-bit
kRGBA_8888_SkColorType.
*/
enum SkColorType {
kUnknown_SkColorType, //!< uninitialized
kAlpha_8_SkColorType, //!< pixel with alpha in 8-bit byte
kRGB_565_SkColorType, //!< pixel with 5 bits red, 6 bits green, 5 bits blue, in 16-bit word
kARGB_4444_SkColorType, //!< pixel with 4 bits for alpha, red, green, blue; in 16-bit word
kRGBA_8888_SkColorType, //!< pixel with 8 bits for red, green, blue, alpha; in 32-bit word
kRGB_888x_SkColorType, //!< pixel with 8 bits each for red, green, blue; in 32-bit word
kBGRA_8888_SkColorType, //!< pixel with 8 bits for blue, green, red, alpha; in 32-bit word
kRGBA_1010102_SkColorType, //!< 10 bits for red, green, blue; 2 bits for alpha; in 32-bit word
kRGB_101010x_SkColorType, //!< pixel with 10 bits each for red, green, blue; in 32-bit word
kGray_8_SkColorType, //!< pixel with grayscale level in 8-bit byte
kRGBA_F16_SkColorType, //!< pixel with half floats for red, green, blue, alpha; in 64-bit word
kRGBA_F32_SkColorType, //!< pixel using C float for red, green, blue, alpha; in 128-bit word
kLastEnum_SkColorType = kRGBA_F32_SkColorType,//!< last valid value
#if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
kN32_SkColorType = kBGRA_8888_SkColorType,//!< native ARGB 32-bit encoding
#elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
kN32_SkColorType = kRGBA_8888_SkColorType,//!< native ARGB 32-bit encoding
#else
#error "SK_*32_SHIFT values must correspond to BGRA or RGBA byte order"
#endif
};
/** Returns the number of bytes required to store a pixel, including unused padding.
Returns zero if ct is kUnknown_SkColorType or invalid.
@param ct one of:
kUnknown_SkColorType, kAlpha_8_SkColorType, kRGB_565_SkColorType,
kARGB_4444_SkColorType, kRGBA_8888_SkColorType, kRGB_888x_SkColorType,
kBGRA_8888_SkColorType, kRGBA_1010102_SkColorType, kRGB_101010x_SkColorType,
kGray_8_SkColorType, kRGBA_F16_SkColorType
@return bytes per pixel
*/
SK_API int SkColorTypeBytesPerPixel(SkColorType ct);
/** Returns true if SkColorType always decodes alpha to 1.0, making the pixel
fully opaque. If true, SkColorType does not reserve bits to encode alpha.
@param ct one of:
kUnknown_SkColorType, kAlpha_8_SkColorType, kRGB_565_SkColorType,
kARGB_4444_SkColorType, kRGBA_8888_SkColorType, kRGB_888x_SkColorType,
kBGRA_8888_SkColorType, kRGBA_1010102_SkColorType, kRGB_101010x_SkColorType,
kGray_8_SkColorType, kRGBA_F16_SkColorType
@return true if alpha is always set to 1.0
*/
SK_API bool SkColorTypeIsAlwaysOpaque(SkColorType ct);
/** Returns true if canonical can be set to a valid SkAlphaType for colorType. If
there is more than one valid canonical SkAlphaType, set to alphaType, if valid.
If true is returned and canonical is not nullptr, store valid SkAlphaType.
Returns false only if alphaType is kUnknown_SkAlphaType, color type is not
kUnknown_SkColorType, and SkColorType is not always opaque. If false is returned,
canonical is ignored.
For kUnknown_SkColorType: set canonical to kUnknown_SkAlphaType and return true.
For kAlpha_8_SkColorType: set canonical to kPremul_SkAlphaType or
kOpaque_SkAlphaType and return true if alphaType is not kUnknown_SkAlphaType.
For kRGB_565_SkColorType, kRGB_888x_SkColorType, kRGB_101010x_SkColorType, and
kGray_8_SkColorType: set canonical to kOpaque_SkAlphaType and return true.
For kARGB_4444_SkColorType, kRGBA_8888_SkColorType, kBGRA_8888_SkColorType,
kRGBA_1010102_SkColorType, and kRGBA_F16_SkColorType: set canonical to alphaType
and return true if alphaType is not kUnknown_SkAlphaType.
@param colorType one of:
kUnknown_SkColorType, kAlpha_8_SkColorType, kRGB_565_SkColorType,
kARGB_4444_SkColorType, kRGBA_8888_SkColorType, kRGB_888x_SkColorType,
kBGRA_8888_SkColorType, kRGBA_1010102_SkColorType, kRGB_101010x_SkColorType,
kGray_8_SkColorType, kRGBA_F16_SkColorType
@param alphaType one of:
kUnknown_SkAlphaType, kOpaque_SkAlphaType, kPremul_SkAlphaType,
kUnpremul_SkAlphaType
@param canonical storage for SkAlphaType
@return true if valid SkAlphaType can be associated with colorType
*/
SK_API bool SkColorTypeValidateAlphaType(SkColorType colorType, SkAlphaType alphaType,
SkAlphaType* canonical = nullptr);
/** \enum SkImageInfo::SkYUVColorSpace
Describes color range of YUV pixels. The color mapping from YUV to RGB varies
depending on the source. YUV pixels may be generated by JPEG images, standard
video streams, or high definition video streams. Each has its own mapping from
YUV and RGB.
JPEG YUV values encode the full range of 0 to 255 for all three components.
Video YUV values range from 16 to 235 for all three components. Details of
encoding and conversion to RGB are described in YCbCr color space.
*/
enum SkYUVColorSpace {
kJPEG_SkYUVColorSpace, //!< describes full range
kRec601_SkYUVColorSpace, //!< describes SDTV range
kRec709_SkYUVColorSpace, //!< describes HDTV range
kLastEnum_SkYUVColorSpace = kRec709_SkYUVColorSpace, //!< last valid value
};
/** \struct SkImageInfo
Describes pixel dimensions and encoding. SkBitmap, SkImage, PixMap, and SkSurface
can be created from SkImageInfo. SkImageInfo can be retrieved from SkBitmap and
SkPixmap, but not from SkImage and SkSurface. For example, SkImage and SkSurface
implementations may defer pixel depth, so may not completely specify SkImageInfo.
SkImageInfo contains dimensions, the pixel integral width and height. It encodes
how pixel bits describe alpha, transparency; color components red, blue,
and green; and SkColorSpace, the range and linearity of colors.
*/
struct SK_API SkImageInfo {
public:
/** Creates an empty SkImageInfo with kUnknown_SkColorType, kUnknown_SkAlphaType,
a width and height of zero, and no SkColorSpace.
@return empty SkImageInfo
*/
SkImageInfo()
: fColorSpace(nullptr)
, fDimensions{0, 0}
, fColorType(kUnknown_SkColorType)
, fAlphaType(kUnknown_SkAlphaType)
{}
/** Creates SkImageInfo from integral dimensions width and height, SkColorType ct,
SkAlphaType at, and optionally SkColorSpace cs.
If SkColorSpace cs is nullptr and SkImageInfo is part of drawing source: SkColorSpace
defaults to sRGB, mapping into SkSurface SkColorSpace.
Parameters are not validated to see if their values are legal, or that the
combination is supported.
@param width pixel column count; must be zero or greater
@param height pixel row count; must be zero or greater
@param ct one of:
kUnknown_SkColorType, kAlpha_8_SkColorType, kRGB_565_SkColorType,
kARGB_4444_SkColorType, kRGBA_8888_SkColorType, kRGB_888x_SkColorType,
kBGRA_8888_SkColorType, kRGBA_1010102_SkColorType, kRGB_101010x_SkColorType,
kGray_8_SkColorType, kRGBA_F16_SkColorType
@param at one of:
kUnknown_SkAlphaType, kOpaque_SkAlphaType, kPremul_SkAlphaType,
kUnpremul_SkAlphaType
@param cs range of colors; may be nullptr
@return created SkImageInfo
*/
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at,
sk_sp<SkColorSpace> cs = nullptr) {
return SkImageInfo(width, height, ct, at, std::move(cs));
}
/** Creates SkImageInfo from integral dimensions width and height, kN32_SkColorType,
SkAlphaType at, and optionally SkColorSpace cs. kN32_SkColorType will equal either
kBGRA_8888_SkColorType or kRGBA_8888_SkColorType, whichever is optimal.
If SkColorSpace cs is nullptr and SkImageInfo is part of drawing source: SkColorSpace
defaults to sRGB, mapping into SkSurface SkColorSpace.
Parameters are not validated to see if their values are legal, or that the
combination is supported.
@param width pixel column count; must be zero or greater
@param height pixel row count; must be zero or greater
@param at one of:
kUnknown_SkAlphaType, kOpaque_SkAlphaType, kPremul_SkAlphaType,
kUnpremul_SkAlphaType
@param cs range of colors; may be nullptr
@return created SkImageInfo
*/
static SkImageInfo MakeN32(int width, int height, SkAlphaType at,
sk_sp<SkColorSpace> cs = nullptr) {
return Make(width, height, kN32_SkColorType, at, std::move(cs));
}
/** Creates SkImageInfo from integral dimensions width and height, kN32_SkColorType,
SkAlphaType at, with sRGB SkColorSpace.
Parameters are not validated to see if their values are legal, or that the
combination is supported.
@param width pixel column count; must be zero or greater
@param height pixel row count; must be zero or greater
@param at one of:
kUnknown_SkAlphaType, kOpaque_SkAlphaType, kPremul_SkAlphaType,
kUnpremul_SkAlphaType
@return created SkImageInfo
*/
static SkImageInfo MakeS32(int width, int height, SkAlphaType at);
/** Creates SkImageInfo from integral dimensions width and height, kN32_SkColorType,
kPremul_SkAlphaType, with optional SkColorSpace.
If SkColorSpace cs is nullptr and SkImageInfo is part of drawing source: SkColorSpace
defaults to sRGB, mapping into SkSurface SkColorSpace.
Parameters are not validated to see if their values are legal, or that the
combination is supported.
@param width pixel column count; must be zero or greater
@param height pixel row count; must be zero or greater
@param cs range of colors; may be nullptr
@return created SkImageInfo
*/
static SkImageInfo MakeN32Premul(int width, int height, sk_sp<SkColorSpace> cs = nullptr) {
return Make(width, height, kN32_SkColorType, kPremul_SkAlphaType, std::move(cs));
}
/** Creates SkImageInfo from integral dimensions width and height, kN32_SkColorType,
kPremul_SkAlphaType, with SkColorSpace set to nullptr.
If SkImageInfo is part of drawing source: SkColorSpace defaults to sRGB, mapping
into SkSurface SkColorSpace.
Parameters are not validated to see if their values are legal, or that the
combination is supported.
@param size width and height, each must be zero or greater
@return created SkImageInfo
*/
static SkImageInfo MakeN32Premul(const SkISize& size) {
return MakeN32Premul(size.width(), size.height());
}
/** Creates SkImageInfo from integral dimensions width and height, kAlpha_8_SkColorType,
kPremul_SkAlphaType, with SkColorSpace set to nullptr.
@param width pixel column count; must be zero or greater
@param height pixel row count; must be zero or greater
@return created SkImageInfo
*/
static SkImageInfo MakeA8(int width, int height) {
return Make(width, height, kAlpha_8_SkColorType, kPremul_SkAlphaType, nullptr);
}
/** Creates SkImageInfo from integral dimensions width and height, kUnknown_SkColorType,
kUnknown_SkAlphaType, with SkColorSpace set to nullptr.
Returned SkImageInfo as part of source does not draw, and as part of destination
can not be drawn to.
@param width pixel column count; must be zero or greater
@param height pixel row count; must be zero or greater
@return created SkImageInfo
*/
static SkImageInfo MakeUnknown(int width, int height) {
return Make(width, height, kUnknown_SkColorType, kUnknown_SkAlphaType, nullptr);
}
/** Creates SkImageInfo from integral dimensions width and height set to zero,
kUnknown_SkColorType, kUnknown_SkAlphaType, with SkColorSpace set to nullptr.
Returned SkImageInfo as part of source does not draw, and as part of destination
can not be drawn to.
@return created SkImageInfo
*/
static SkImageInfo MakeUnknown() {
return MakeUnknown(0, 0);
}
/** Returns pixel count in each row.
@return pixel width
*/
int width() const { return fDimensions.width(); }
/** Returns pixel row count.
@return pixel height
*/
int height() const { return fDimensions.height(); }
/** Returns SkColorType, one of:
kUnknown_SkColorType, kAlpha_8_SkColorType, kRGB_565_SkColorType,
kARGB_4444_SkColorType, kRGBA_8888_SkColorType, kRGB_888x_SkColorType,
kBGRA_8888_SkColorType, kRGBA_1010102_SkColorType, kRGB_101010x_SkColorType,
kGray_8_SkColorType, kRGBA_F16_SkColorType.
@return SkColorType
*/
SkColorType colorType() const { return fColorType; }
/** Returns SkAlphaType, one of:
kUnknown_SkAlphaType, kOpaque_SkAlphaType, kPremul_SkAlphaType,
kUnpremul_SkAlphaType.
@return SkAlphaType
*/
SkAlphaType alphaType() const { return fAlphaType; }
/** Returns SkColorSpace, the range of colors. The reference count of
SkColorSpace is unchanged. The returned SkColorSpace is immutable.
@return SkColorSpace, or nullptr
*/
SkColorSpace* colorSpace() const { return fColorSpace.get(); }
/** Returns smart pointer to SkColorSpace, the range of colors. The smart pointer
tracks the number of objects sharing this SkColorSpace reference so the memory
is released when the owners destruct.
The returned SkColorSpace is immutable.
@return SkColorSpace wrapped in a smart pointer
*/
sk_sp<SkColorSpace> refColorSpace() const { return fColorSpace; }
/** Returns if SkImageInfo describes an empty area of pixels by checking if either
width or height is zero or smaller.
@return true if either dimension is zero or smaller
*/
bool isEmpty() const { return fDimensions.isEmpty(); }
/** Returns true if SkAlphaType is set to hint that all pixels are opaque; their
alpha value is implicitly or explicitly 1.0. If true, and all pixels are
not opaque, Skia may draw incorrectly.
Does not check if SkColorType allows alpha, or if any pixel value has
transparency.
@return true if SkAlphaType is kOpaque_SkAlphaType
*/
bool isOpaque() const {
return SkAlphaTypeIsOpaque(fAlphaType);
}
/** Returns SkISize { width(), height() }.
@return integral size of width() and height()
*/
SkISize dimensions() const { return fDimensions; }
/** Returns SkIRect { 0, 0, width(), height() }.
@return integral rectangle from origin to width() and height()
*/
SkIRect bounds() const { return SkIRect::MakeSize(fDimensions); }
/** Returns true if associated SkColorSpace is not nullptr, and SkColorSpace gamma
is approximately the same as sRGB.
This includes the
@return true if SkColorSpace gamma is approximately the same as sRGB
*/
bool gammaCloseToSRGB() const {
return fColorSpace && fColorSpace->gammaCloseToSRGB();
}
/** Creates SkImageInfo with the same SkColorType, SkColorSpace, and SkAlphaType,
with dimensions set to width and height.
@param newWidth pixel column count; must be zero or greater
@param newHeight pixel row count; must be zero or greater
@return created SkImageInfo
*/
SkImageInfo makeWH(int newWidth, int newHeight) const {
return Make(newWidth, newHeight, fColorType, fAlphaType, fColorSpace);
}
/** Creates SkImageInfo with same SkColorType, SkColorSpace, width, and height,
with SkAlphaType set to newAlphaType.
Created SkImageInfo contains newAlphaType even if it is incompatible with
SkColorType, in which case SkAlphaType in SkImageInfo is ignored.
@param newAlphaType one of:
kUnknown_SkAlphaType, kOpaque_SkAlphaType, kPremul_SkAlphaType,
kUnpremul_SkAlphaType
@return created SkImageInfo
*/
SkImageInfo makeAlphaType(SkAlphaType newAlphaType) const {
return Make(this->width(), this->height(), fColorType, newAlphaType, fColorSpace);
}
/** Creates SkImageInfo with same SkAlphaType, SkColorSpace, width, and height,
with SkColorType set to newColorType.
@param newColorType one of:
kUnknown_SkColorType, kAlpha_8_SkColorType, kRGB_565_SkColorType,
kARGB_4444_SkColorType, kRGBA_8888_SkColorType, kRGB_888x_SkColorType,
kBGRA_8888_SkColorType, kRGBA_1010102_SkColorType,
kRGB_101010x_SkColorType, kGray_8_SkColorType, kRGBA_F16_SkColorType
@return created SkImageInfo
*/
SkImageInfo makeColorType(SkColorType newColorType) const {
return Make(this->width(), this->height(), newColorType, fAlphaType, fColorSpace);
}
/** Creates SkImageInfo with same SkAlphaType, SkColorType, width, and height,
with SkColorSpace set to cs.
@param cs range of colors; may be nullptr
@return created SkImageInfo
*/
SkImageInfo makeColorSpace(sk_sp<SkColorSpace> cs) const {
return Make(this->width(), this->height(), fColorType, fAlphaType, std::move(cs));
}
/** Returns number of bytes per pixel required by SkColorType.
Returns zero if colorType( is kUnknown_SkColorType.
@return bytes in pixel
*/
int bytesPerPixel() const;
/** Returns bit shift converting row bytes to row pixels.
Returns zero for kUnknown_SkColorType.
@return one of: 0, 1, 2, 3; left shift to convert pixels to bytes
*/
int shiftPerPixel() const;
/** Returns minimum bytes per row, computed from pixel width() and SkColorType, which
specifies bytesPerPixel(). SkBitmap maximum value for row bytes must fit
in 31 bits.
@return width() times bytesPerPixel() as unsigned 64-bit integer
*/
uint64_t minRowBytes64() const { return sk_64_mul(this->width(), this->bytesPerPixel()); }
/** Returns minimum bytes per row, computed from pixel width() and SkColorType, which
specifies bytesPerPixel(). SkBitmap maximum value for row bytes must fit
in 31 bits.
@return width() times bytesPerPixel() as signed 32-bit integer
*/
size_t minRowBytes() const {
uint64_t minRowBytes = this->minRowBytes64();
if (!SkTFitsIn<int32_t>(minRowBytes)) {
return 0;
}
return SkTo<int32_t>(minRowBytes);
}
/** Returns byte offset of pixel from pixel base address.
Asserts in debug build if x or y is outside of bounds. Does not assert if
rowBytes is smaller than minRowBytes(), even though result may be incorrect.
@param x column index, zero or greater, and less than width()
@param y row index, zero or greater, and less than height()
@param rowBytes size of pixel row or larger
@return offset within pixel array
*/
size_t computeOffset(int x, int y, size_t rowBytes) const;
/** Compares SkImageInfo with other, and returns true if width, height, SkColorType,
SkAlphaType, and SkColorSpace are equivalent.
@param other SkImageInfo to compare
@return true if SkImageInfo equals other
*/
bool operator==(const SkImageInfo& other) const {
return fDimensions == other.fDimensions &&
fColorType == other.fColorType && fAlphaType == other.fAlphaType &&
SkColorSpace::Equals(fColorSpace.get(), other.fColorSpace.get());
}
/** Compares SkImageInfo with other, and returns true if width, height, SkColorType,
SkAlphaType, and SkColorSpace are not equivalent.
@param other SkImageInfo to compare
@return true if SkImageInfo is not equal to other
*/
bool operator!=(const SkImageInfo& other) const {
return !(*this == other);
}
/** Returns storage required by pixel array, given SkImageInfo dimensions, SkColorType,
and rowBytes. rowBytes is assumed to be at least as large as minRowBytes().
Returns zero if height is zero.
Returns SIZE_MAX if answer exceeds the range of size_t.
@param rowBytes size of pixel row or larger
@return memory required by pixel buffer
*/
size_t computeByteSize(size_t rowBytes) const;
/** Returns storage required by pixel array, given SkImageInfo dimensions, and
SkColorType. Uses minRowBytes() to compute bytes for pixel row.
Returns zero if height is zero.
Returns SIZE_MAX if answer exceeds the range of size_t.
@return least memory required by pixel buffer
*/
size_t computeMinByteSize() const {
return this->computeByteSize(this->minRowBytes());
}
/** Returns true if byteSize equals SIZE_MAX. computeByteSize() and
computeMinByteSize() return SIZE_MAX if size_t can not hold buffer size.
@param byteSize result of computeByteSize() or computeMinByteSize()
@return true if computeByteSize() or computeMinByteSize() result exceeds size_t
*/
static bool ByteSizeOverflowed(size_t byteSize) {
return SIZE_MAX == byteSize;
}
/** Returns true if rowBytes is smaller than width times pixel size.
@param rowBytes size of pixel row or larger
@return true if rowBytes is large enough to contain pixel row
*/
bool validRowBytes(size_t rowBytes) const {
return rowBytes >= this->minRowBytes64();
}
/** Creates an empty SkImageInfo with kUnknown_SkColorType, kUnknown_SkAlphaType,
a width and height of zero, and no SkColorSpace.
*/
void reset() {
fColorSpace = nullptr;
fDimensions = {0, 0};
fColorType = kUnknown_SkColorType;
fAlphaType = kUnknown_SkAlphaType;
}
/** Asserts if internal values are illegal or inconsistent. Only available if
SK_DEBUG is defined at compile time.
*/
SkDEBUGCODE(void validate() const;)
private:
sk_sp<SkColorSpace> fColorSpace;
SkISize fDimensions;
SkColorType fColorType;
SkAlphaType fAlphaType;
SkImageInfo(int width, int height, SkColorType ct, SkAlphaType at, sk_sp<SkColorSpace> cs)
: fColorSpace(std::move(cs))
, fDimensions{width, height}
, fColorType(ct)
, fAlphaType(at)
{}
};
#endif

195
skia/include/core/SkLights.h vendored Normal file
View File

@ -0,0 +1,195 @@
/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkLights_DEFINED
#define SkLights_DEFINED
#include "SkPoint3.h"
#include "SkRefCnt.h"
#include "../private/SkTArray.h"
class SkColorSpaceXformer;
class SkReadBuffer;
class SkWriteBuffer;
/** \class SkLights
SkLights encapsulates a set of directional, point and ambient lights for use with the
SkLightingShader.
*/
class SK_API SkLights : public SkRefCnt {
public:
class Light {
public:
enum LightType {
kDirectional_LightType,
kPoint_LightType
};
Light(const Light& other)
: fType(other.fType)
, fColor(other.fColor)
, fDirOrPos(other.fDirOrPos)
, fIntensity(other.fIntensity) {}
Light(Light&& other)
: fType(other.fType)
, fColor(other.fColor)
, fDirOrPos(other.fDirOrPos)
, fIntensity(other.fIntensity) {}
static Light MakeDirectional(const SkColor3f& color, const SkVector3& dir) {
Light light(kDirectional_LightType, color, dir, 0.0f);
if (!light.fDirOrPos.normalize()) {
light.fDirOrPos.set(0.0f, 0.0f, 1.0f);
}
return light;
}
static Light MakePoint(const SkColor3f& color, const SkPoint3& pos, SkScalar intensity) {
return Light(kPoint_LightType, color, pos, intensity);
}
LightType type() const { return fType; }
const SkColor3f& color() const { return fColor; }
const SkVector3& dir() const {
SkASSERT(kDirectional_LightType == fType);
return fDirOrPos;
}
const SkPoint3& pos() const {
SkASSERT(kPoint_LightType == fType);
return fDirOrPos;
}
SkScalar intensity() const {
SkASSERT(kPoint_LightType == fType);
return fIntensity;
}
Light& operator=(const Light& other) {
if (this == &other) {
return *this;
}
fType = other.fType;
fColor = other.fColor;
fDirOrPos = other.fDirOrPos;
fIntensity = other.fIntensity;
return *this;
}
bool operator==(const Light& other) {
return (fType == other.fType) &&
(fColor == other.fColor) &&
(fDirOrPos == other.fDirOrPos) &&
(fIntensity == other.fIntensity);
}
bool operator!=(const Light& other) { return !(this->operator==(other)); }
private:
friend class SkLights;
Light(LightType type, const SkColor3f& color, const SkVector3& dirOrPos,
SkScalar intensity)
: fType(type)
, fColor(color)
, fDirOrPos(dirOrPos)
, fIntensity(intensity) {}
LightType fType;
SkColor3f fColor; // linear (unpremul) color. Range is 0..1 in each channel.
SkVector3 fDirOrPos; // For directional lights, holds the direction towards the
// light (+Z is out of the screen).
// If degenerate, it will be replaced with (0, 0, 1).
// For point lights, holds location of point light
SkScalar fIntensity; // For point lights, dictates the light intensity.
// Simply a multiplier to the final light output value.
};
class Builder {
public:
Builder() : fLights(new SkLights) {}
void add(const Light& light) {
if (fLights) {
fLights->fLights.push_back(light);
}
}
void add(Light&& light) {
if (fLights) {
fLights->fLights.push_back(std::move(light));
}
}
void setAmbientLightColor(const SkColor3f& color) {
if (fLights) {
fLights->fAmbientLightColor = color;
}
}
sk_sp<SkLights> finish() {
return std::move(fLights);
}
private:
sk_sp<SkLights> fLights;
};
/** Returns number of lights not including the ambient light.
@return number of lights not including the ambient light
*/
int numLights() const { return fLights.count(); }
/** Returns the index-th light.
@param index the index of the desired light
@return the index-th light
*/
const Light& light(int index) const { return fLights[index]; }
/** Returns the ambient light.
@return the ambient light
*/
const SkColor3f& ambientLightColor() const {
return fAmbientLightColor;
}
/**
* Recreate an SkLights object that was serialized into a buffer.
*
* @param SkReadBuffer Serialized blob data.
* @return A new SkLights representing the serialized data, or NULL if the buffer is
* invalid.
*/
static sk_sp<SkLights> MakeFromBuffer(SkReadBuffer& buf);
/**
* Serialize to a buffer.
*
* @param buffer the write buffer to write out to
*/
void flatten(SkWriteBuffer& buf) const;
private:
friend class SkLightingShaderImpl;
SkLights() : fAmbientLightColor(SkColor3f::Make(0.0f, 0.0f, 0.0f)) {}
sk_sp<SkLights> makeColorSpace(SkColorSpaceXformer* xformer) const;
SkTArray<Light> fLights;
SkColor3f fAmbientLightColor;
typedef SkRefCnt INHERITED;
};
#endif

93
skia/include/core/SkMallocPixelRef.h vendored Normal file
View File

@ -0,0 +1,93 @@
/*
* 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"
#include "SkRefCnt.h"
#include "SkTypes.h"
class SkData;
struct SkImageInfo;
/** We explicitly use the same allocator for our pixels that SkMask does,
so that we can freely assign memory allocated by one class to the other.
*/
class SK_API SkMallocPixelRef : public SkPixelRef {
public:
/**
* Return a new SkMallocPixelRef with the provided pixel storage, rowBytes,
* and optional colortable. The caller is responsible for managing the
* lifetime of the pixel storage buffer, as this pixelref will not try
* to delete it.
*
* Returns NULL on failure.
*/
static sk_sp<SkPixelRef> MakeDirect(const SkImageInfo&, void* addr, size_t rowBytes);
/**
* Return a new SkMallocPixelRef, automatically allocating storage for the
* pixels. If rowBytes are 0, an optimal value will be chosen automatically.
* If rowBytes is > 0, then it will be respected, or NULL will be returned
* if rowBytes is invalid for the specified info.
*
* This pixelref will ref() the specified colortable (if not NULL).
*
* Returns NULL on failure.
*/
static sk_sp<SkPixelRef> MakeAllocate(const SkImageInfo&, size_t rowBytes);
/**
* Identical to MakeAllocate, except all pixel bytes are zeroed.
*/
static sk_sp<SkPixelRef> MakeZeroed(const SkImageInfo&, size_t rowBytes);
/**
* Return a new SkMallocPixelRef with the provided pixel storage,
* rowBytes, and optional colortable. On destruction, ReleaseProc
* will be called.
*
* If ReleaseProc is NULL, the pixels will never be released. This
* can be useful if the pixels were stack allocated. However, such an
* SkMallocPixelRef must not live beyond its pixels (e.g. by copying
* an SkBitmap pointing to it, or drawing to an SkPicture).
*
* Returns NULL on failure.
*/
typedef void (*ReleaseProc)(void* addr, void* context);
static sk_sp<SkPixelRef> MakeWithProc(const SkImageInfo& info, size_t rowBytes, void* addr,
ReleaseProc proc, void* context);
/**
* Return a new SkMallocPixelRef that will use the provided
* SkData, rowBytes, and optional colortable as pixel storage.
* The SkData will be ref()ed and on destruction of the PielRef,
* the SkData will be unref()ed.
*
* Returns NULL on failure.
*/
static sk_sp<SkPixelRef> MakeWithData(const SkImageInfo&, size_t rowBytes, sk_sp<SkData> data);
protected:
~SkMallocPixelRef() override;
private:
// Uses alloc to implement NewAllocate or NewZeroed.
static sk_sp<SkPixelRef> MakeUsing(void*(*alloc)(size_t),
const SkImageInfo&,
size_t rowBytes);
ReleaseProc fReleaseProc;
void* fReleaseProcContext;
SkMallocPixelRef(const SkImageInfo&, void* addr, size_t rb, ReleaseProc proc, void* context);
typedef SkPixelRef INHERITED;
};
#endif

77
skia/include/core/SkMaskFilter.h vendored Normal file
View File

@ -0,0 +1,77 @@
/*
* Copyright 2006 The Android Open Source Project
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkMaskFilter_DEFINED
#define SkMaskFilter_DEFINED
#include "SkBlurTypes.h"
#include "SkCoverageMode.h"
#include "SkFlattenable.h"
#include "SkScalar.h"
class SkMatrix;
struct SkRect;
class SkString;
/** \class SkMaskFilter
SkMaskFilter is the base class for object that perform transformations on
the mask before drawing it. An example subclass is Blur.
*/
class SK_API SkMaskFilter : public SkFlattenable {
public:
/** Create a blur maskfilter.
* @param style The SkBlurStyle to use
* @param sigma Standard deviation of the Gaussian blur to apply. Must be > 0.
* @param respectCTM if true the blur's sigma is modified by the CTM.
* @return The new blur maskfilter
*/
static sk_sp<SkMaskFilter> MakeBlur(SkBlurStyle style, SkScalar sigma,
bool respectCTM = true);
/**
* Construct a maskfilter whose effect is to first apply the inner filter and then apply
* the outer filter to the result of the inner's. Returns nullptr on failure.
*/
static sk_sp<SkMaskFilter> MakeCompose(sk_sp<SkMaskFilter> outer, sk_sp<SkMaskFilter> inner);
/**
* Compose two maskfilters together using a coverage mode. Returns nullptr on failure.
*/
static sk_sp<SkMaskFilter> MakeCombine(sk_sp<SkMaskFilter> filterA, sk_sp<SkMaskFilter> filterB,
SkCoverageMode mode);
/**
* Construct a maskfilter with an additional transform.
*
* Note: unlike shader local matrices, this transform composes next to the CTM.
*
* TotalMatrix = CTM x MaskFilterMatrix x (optional/downstream) ShaderLocalMatrix
*/
sk_sp<SkMaskFilter> makeWithMatrix(const SkMatrix&) const;
static SkFlattenable::Type GetFlattenableType() {
return kSkMaskFilter_Type;
}
SkFlattenable::Type getFlattenableType() const override {
return kSkMaskFilter_Type;
}
static sk_sp<SkMaskFilter> Deserialize(const void* data, size_t size,
const SkDeserialProcs* procs = nullptr) {
return sk_sp<SkMaskFilter>(static_cast<SkMaskFilter*>(
SkFlattenable::Deserialize(
kSkMaskFilter_Type, data, size, procs).release()));
}
private:
static void RegisterFlattenables();
friend class SkFlattenable;
};
#endif

75
skia/include/core/SkMath.h vendored Normal file
View File

@ -0,0 +1,75 @@
/*
* 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 SkMath_DEFINED
#define SkMath_DEFINED
#include "SkTypes.h"
// 64bit -> 32bit utilities
// 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;
}
///////////////////////////////////////////////////////////////////////////////
/** Given an integer and a positive (max) integer, return the value
* pinned against 0 and max, inclusive.
* @param value The value we want returned pinned between [0...max]
* @param max The positive max value
* @return 0 if value < 0, max if value > max, else value
*/
static inline int SkClampMax(int value, int max) {
// ensure that max is positive
SkASSERT(max >= 0);
if (value < 0) {
value = 0;
}
if (value > max) {
value = max;
}
return value;
}
/**
* Returns true if value is a power of 2. Does not explicitly check for
* value <= 0.
*/
template <typename T> constexpr inline bool SkIsPow2(T value) {
return (value & (value - 1)) == 0;
}
///////////////////////////////////////////////////////////////////////////////
/**
* 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) {
SkASSERT(a <= 32767);
SkASSERT(b <= 32767);
SkASSERT(shift > 0 && shift <= 8);
unsigned prod = a*b + (1 << (shift - 1));
return (prod + (prod >> shift)) >> shift;
}
/**
* Return a*b/255, rounding any fractional bits.
* Only valid if a and b are unsigned and <= 32767.
*/
static inline U8CPU SkMulDiv255Round(U16CPU a, U16CPU b) {
SkASSERT(a <= 32767);
SkASSERT(b <= 32767);
unsigned prod = a*b + 128;
return (prod + (prod >> 8)) >> 8;
}
#endif

1863
skia/include/core/SkMatrix.h vendored Normal file

File diff suppressed because it is too large Load Diff

495
skia/include/core/SkMatrix44.h vendored Normal file
View File

@ -0,0 +1,495 @@
/*
* 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 SkMatrix44_DEFINED
#define SkMatrix44_DEFINED
#include "SkMatrix.h"
#include "SkScalar.h"
#include <atomic>
#include <cstring>
#ifdef SK_MSCALAR_IS_DOUBLE
#ifdef SK_MSCALAR_IS_FLOAT
#error "can't define MSCALAR both as DOUBLE and FLOAT"
#endif
typedef double SkMScalar;
static inline double SkFloatToMScalar(float x) {
return static_cast<double>(x);
}
static inline float SkMScalarToFloat(double x) {
return static_cast<float>(x);
}
static inline double SkDoubleToMScalar(double x) {
return x;
}
static inline double SkMScalarToDouble(double x) {
return x;
}
static inline double SkMScalarAbs(double x) {
return fabs(x);
}
static const SkMScalar SK_MScalarPI = 3.141592653589793;
#define SkMScalarFloor(x) sk_double_floor(x)
#define SkMScalarCeil(x) sk_double_ceil(x)
#define SkMScalarRound(x) sk_double_round(x)
#define SkMScalarFloorToInt(x) sk_double_floor2int(x)
#define SkMScalarCeilToInt(x) sk_double_ceil2int(x)
#define SkMScalarRoundToInt(x) sk_double_round2int(x)
#elif defined SK_MSCALAR_IS_FLOAT
#ifdef SK_MSCALAR_IS_DOUBLE
#error "can't define MSCALAR both as DOUBLE and FLOAT"
#endif
typedef float SkMScalar;
static inline float SkFloatToMScalar(float x) {
return x;
}
static inline float SkMScalarToFloat(float x) {
return x;
}
static inline float SkDoubleToMScalar(double x) {
return sk_double_to_float(x);
}
static inline double SkMScalarToDouble(float x) {
return static_cast<double>(x);
}
static inline float SkMScalarAbs(float x) {
return sk_float_abs(x);
}
static const SkMScalar SK_MScalarPI = 3.14159265f;
#define SkMScalarFloor(x) sk_float_floor(x)
#define SkMScalarCeil(x) sk_float_ceil(x)
#define SkMScalarRound(x) sk_float_round(x)
#define SkMScalarFloorToInt(x) sk_float_floor2int(x)
#define SkMScalarCeilToInt(x) sk_float_ceil2int(x)
#define SkMScalarRoundToInt(x) sk_float_round2int(x)
#endif
#define SkIntToMScalar(n) static_cast<SkMScalar>(n)
#define SkMScalarToScalar(x) SkMScalarToFloat(x)
#define SkScalarToMScalar(x) SkFloatToMScalar(x)
static const SkMScalar SK_MScalar1 = 1;
///////////////////////////////////////////////////////////////////////////////
struct SkVector4 {
SkScalar fData[4];
SkVector4() {
this->set(0, 0, 0, 1);
}
SkVector4(const SkVector4& src) {
memcpy(fData, src.fData, sizeof(fData));
}
SkVector4(SkScalar x, SkScalar y, SkScalar z, SkScalar w = SK_Scalar1) {
fData[0] = x;
fData[1] = y;
fData[2] = z;
fData[3] = w;
}
SkVector4& operator=(const SkVector4& src) {
memcpy(fData, src.fData, sizeof(fData));
return *this;
}
bool operator==(const SkVector4& v) {
return fData[0] == v.fData[0] && fData[1] == v.fData[1] &&
fData[2] == v.fData[2] && fData[3] == v.fData[3];
}
bool operator!=(const SkVector4& v) {
return !(*this == v);
}
bool equals(SkScalar x, SkScalar y, SkScalar z, SkScalar w = SK_Scalar1) {
return fData[0] == x && fData[1] == y &&
fData[2] == z && fData[3] == w;
}
void set(SkScalar x, SkScalar y, SkScalar z, SkScalar w = SK_Scalar1) {
fData[0] = x;
fData[1] = y;
fData[2] = z;
fData[3] = w;
}
};
/** \class SkMatrix44
The SkMatrix44 class holds a 4x4 matrix.
SkMatrix44 is not thread safe unless you've first called SkMatrix44::getType().
*/
class SK_API SkMatrix44 {
public:
enum Uninitialized_Constructor {
kUninitialized_Constructor
};
enum Identity_Constructor {
kIdentity_Constructor
};
SkMatrix44(Uninitialized_Constructor) {} // ironically, cannot be constexpr
constexpr SkMatrix44(Identity_Constructor)
: fMat{{ 1, 0, 0, 0, },
{ 0, 1, 0, 0, },
{ 0, 0, 1, 0, },
{ 0, 0, 0, 1, }}
, fTypeMask(kIdentity_Mask)
{}
constexpr SkMatrix44() : SkMatrix44{kIdentity_Constructor} {}
SkMatrix44(const SkMatrix44& src) {
memcpy(fMat, src.fMat, sizeof(fMat));
fTypeMask.store(src.fTypeMask, std::memory_order_relaxed);
}
SkMatrix44(const SkMatrix44& a, const SkMatrix44& b) {
this->setConcat(a, b);
}
SkMatrix44& operator=(const SkMatrix44& src) {
if (&src != this) {
memcpy(fMat, src.fMat, sizeof(fMat));
fTypeMask.store(src.fTypeMask, std::memory_order_relaxed);
}
return *this;
}
bool operator==(const SkMatrix44& other) const;
bool operator!=(const SkMatrix44& other) const {
return !(other == *this);
}
/* When converting from SkMatrix44 to SkMatrix, the third row and
* column is dropped. When converting from SkMatrix to SkMatrix44
* the third row and column remain as identity:
* [ a b c ] [ a b 0 c ]
* [ d e f ] -> [ d e 0 f ]
* [ g h i ] [ 0 0 1 0 ]
* [ g h 0 i ]
*/
SkMatrix44(const SkMatrix&);
SkMatrix44& operator=(const SkMatrix& src);
operator SkMatrix() const;
/**
* Return a reference to a const identity matrix
*/
static const SkMatrix44& I();
enum TypeMask {
kIdentity_Mask = 0,
kTranslate_Mask = 0x01, //!< set if the matrix has translation
kScale_Mask = 0x02, //!< set if the matrix has any scale != 1
kAffine_Mask = 0x04, //!< set if the matrix skews or rotates
kPerspective_Mask = 0x08 //!< set if the matrix is in perspective
};
/**
* Returns a bitfield describing the transformations the matrix may
* perform. The bitfield is computed conservatively, so it may include
* false positives. For example, when kPerspective_Mask is true, all
* other bits may be set to true even in the case of a pure perspective
* transform.
*/
inline TypeMask getType() const {
if (fTypeMask.load(std::memory_order_relaxed) & kUnknown_Mask) {
fTypeMask.store(this->computeTypeMask(), std::memory_order_relaxed);
}
SkASSERT(!(fTypeMask & kUnknown_Mask));
return (TypeMask)fTypeMask.load(std::memory_order_relaxed);
}
/**
* Return true if the matrix is identity.
*/
inline bool isIdentity() const {
return kIdentity_Mask == this->getType();
}
/**
* Return true if the matrix contains translate or is identity.
*/
inline bool isTranslate() const {
return !(this->getType() & ~kTranslate_Mask);
}
/**
* Return true if the matrix only contains scale or translate or is identity.
*/
inline bool isScaleTranslate() const {
return !(this->getType() & ~(kScale_Mask | kTranslate_Mask));
}
/**
* Returns true if the matrix only contains scale or is identity.
*/
inline bool isScale() const {
return !(this->getType() & ~kScale_Mask);
}
inline bool hasPerspective() const {
return SkToBool(this->getType() & kPerspective_Mask);
}
void setIdentity();
inline void reset() { this->setIdentity();}
/**
* get a value from the matrix. The row,col parameters work as follows:
* (0, 0) scale-x
* (0, 3) translate-x
* (3, 0) perspective-x
*/
inline SkMScalar get(int row, int col) const {
SkASSERT((unsigned)row <= 3);
SkASSERT((unsigned)col <= 3);
return fMat[col][row];
}
/**
* set a value in the matrix. The row,col parameters work as follows:
* (0, 0) scale-x
* (0, 3) translate-x
* (3, 0) perspective-x
*/
inline void set(int row, int col, SkMScalar value) {
SkASSERT((unsigned)row <= 3);
SkASSERT((unsigned)col <= 3);
fMat[col][row] = value;
this->dirtyTypeMask();
}
inline double getDouble(int row, int col) const {
return SkMScalarToDouble(this->get(row, col));
}
inline void setDouble(int row, int col, double value) {
this->set(row, col, SkDoubleToMScalar(value));
}
inline float getFloat(int row, int col) const {
return SkMScalarToFloat(this->get(row, col));
}
inline void setFloat(int row, int col, float value) {
this->set(row, col, SkFloatToMScalar(value));
}
/** These methods allow one to efficiently read matrix entries into an
* array. The given array must have room for exactly 16 entries. Whenever
* possible, they will try to use memcpy rather than an entry-by-entry
* copy.
*
* Col major indicates that consecutive elements of columns will be stored
* contiguously in memory. Row major indicates that consecutive elements
* of rows will be stored contiguously in memory.
*/
void asColMajorf(float[]) const;
void asColMajord(double[]) const;
void asRowMajorf(float[]) const;
void asRowMajord(double[]) const;
/** These methods allow one to efficiently set all matrix entries from an
* array. The given array must have room for exactly 16 entries. Whenever
* possible, they will try to use memcpy rather than an entry-by-entry
* copy.
*
* Col major indicates that input memory will be treated as if consecutive
* elements of columns are stored contiguously in memory. Row major
* indicates that input memory will be treated as if consecutive elements
* of rows are stored contiguously in memory.
*/
void setColMajorf(const float[]);
void setColMajord(const double[]);
void setRowMajorf(const float[]);
void setRowMajord(const double[]);
#ifdef SK_MSCALAR_IS_FLOAT
void setColMajor(const SkMScalar data[]) { this->setColMajorf(data); }
void setRowMajor(const SkMScalar data[]) { this->setRowMajorf(data); }
#else
void setColMajor(const SkMScalar data[]) { this->setColMajord(data); }
void setRowMajor(const SkMScalar data[]) { this->setRowMajord(data); }
#endif
/* This sets the top-left of the matrix and clears the translation and
* perspective components (with [3][3] set to 1). m_ij is interpreted
* as the matrix entry at row = i, col = j. */
void set3x3(SkMScalar m_00, SkMScalar m_10, SkMScalar m_20,
SkMScalar m_01, SkMScalar m_11, SkMScalar m_21,
SkMScalar m_02, SkMScalar m_12, SkMScalar m_22);
void set3x3RowMajorf(const float[]);
void setTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz);
void preTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz);
void postTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz);
void setScale(SkMScalar sx, SkMScalar sy, SkMScalar sz);
void preScale(SkMScalar sx, SkMScalar sy, SkMScalar sz);
void postScale(SkMScalar sx, SkMScalar sy, SkMScalar sz);
inline void setScale(SkMScalar scale) {
this->setScale(scale, scale, scale);
}
inline void preScale(SkMScalar scale) {
this->preScale(scale, scale, scale);
}
inline void postScale(SkMScalar scale) {
this->postScale(scale, scale, scale);
}
void setRotateDegreesAbout(SkMScalar x, SkMScalar y, SkMScalar z,
SkMScalar degrees) {
this->setRotateAbout(x, y, z, degrees * SK_MScalarPI / 180);
}
/** Rotate about the vector [x,y,z]. If that vector is not unit-length,
it will be automatically resized.
*/
void setRotateAbout(SkMScalar x, SkMScalar y, SkMScalar z,
SkMScalar radians);
/** Rotate about the vector [x,y,z]. Does not check the length of the
vector, assuming it is unit-length.
*/
void setRotateAboutUnit(SkMScalar x, SkMScalar y, SkMScalar z,
SkMScalar radians);
void setConcat(const SkMatrix44& a, const SkMatrix44& b);
inline void preConcat(const SkMatrix44& m) {
this->setConcat(*this, m);
}
inline void postConcat(const SkMatrix44& m) {
this->setConcat(m, *this);
}
friend SkMatrix44 operator*(const SkMatrix44& a, const SkMatrix44& b) {
return SkMatrix44(a, b);
}
/** If this is invertible, return that in inverse and return true. If it is
not invertible, return false and leave the inverse parameter in an
unspecified state.
*/
bool invert(SkMatrix44* inverse) const;
/** Transpose this matrix in place. */
void transpose();
/** Apply the matrix to the src vector, returning the new vector in dst.
It is legal for src and dst to point to the same memory.
*/
void mapScalars(const SkScalar src[4], SkScalar dst[4]) const;
inline void mapScalars(SkScalar vec[4]) const {
this->mapScalars(vec, vec);
}
#ifdef SK_MSCALAR_IS_DOUBLE
void mapMScalars(const SkMScalar src[4], SkMScalar dst[4]) const;
#elif defined SK_MSCALAR_IS_FLOAT
inline void mapMScalars(const SkMScalar src[4], SkMScalar dst[4]) const {
this->mapScalars(src, dst);
}
#endif
inline void mapMScalars(SkMScalar vec[4]) const {
this->mapMScalars(vec, vec);
}
friend SkVector4 operator*(const SkMatrix44& m, const SkVector4& src) {
SkVector4 dst;
m.mapScalars(src.fData, dst.fData);
return dst;
}
/**
* map an array of [x, y, 0, 1] through the matrix, returning an array
* of [x', y', z', w'].
*
* @param src2 array of [x, y] pairs, with implied z=0 and w=1
* @param count number of [x, y] pairs in src2
* @param dst4 array of [x', y', z', w'] quads as the output.
*/
void map2(const float src2[], int count, float dst4[]) const;
void map2(const double src2[], int count, double dst4[]) const;
/** Returns true if transformating an axis-aligned square in 2d by this matrix
will produce another 2d axis-aligned square; typically means the matrix
is a scale with perhaps a 90-degree rotation. A 3d rotation through 90
degrees into a perpendicular plane collapses a square to a line, but
is still considered to be axis-aligned.
By default, tolerates very slight error due to float imprecisions;
a 90-degree rotation can still end up with 10^-17 of
"non-axis-aligned" result.
*/
bool preserves2dAxisAlignment(SkMScalar epsilon = SK_ScalarNearlyZero) const;
void dump() const;
double determinant() const;
private:
/* This is indexed by [col][row]. */
SkMScalar fMat[4][4];
mutable std::atomic<unsigned> fTypeMask;
static constexpr int kUnknown_Mask = 0x80;
static constexpr int kAllPublic_Masks = 0xF;
void as3x4RowMajorf(float[]) const;
void set3x4RowMajorf(const float[]);
SkMScalar transX() const { return fMat[3][0]; }
SkMScalar transY() const { return fMat[3][1]; }
SkMScalar transZ() const { return fMat[3][2]; }
SkMScalar scaleX() const { return fMat[0][0]; }
SkMScalar scaleY() const { return fMat[1][1]; }
SkMScalar scaleZ() const { return fMat[2][2]; }
SkMScalar perspX() const { return fMat[0][3]; }
SkMScalar perspY() const { return fMat[1][3]; }
SkMScalar perspZ() const { return fMat[2][3]; }
int computeTypeMask() const;
inline void dirtyTypeMask() {
fTypeMask.store(kUnknown_Mask, std::memory_order_relaxed);
}
inline void setTypeMask(int mask) {
SkASSERT(0 == (~(kAllPublic_Masks | kUnknown_Mask) & mask));
fTypeMask.store(mask, std::memory_order_relaxed);
}
/**
* Does not take the time to 'compute' the typemask. Only returns true if
* we already know that this matrix is identity.
*/
inline bool isTriviallyIdentity() const {
return 0 == fTypeMask.load(std::memory_order_relaxed);
}
inline const SkMScalar* values() const { return &fMat[0][0]; }
friend class SkColorSpace;
};
#endif

175
skia/include/core/SkMetaData.h vendored Normal file
View File

@ -0,0 +1,175 @@
/*
* 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 SkMetaData_DEFINED
#define SkMetaData_DEFINED
#include "SkScalar.h"
class SkRefCnt;
class SK_API SkMetaData {
public:
/**
* Used to manage the life-cycle of a ptr in the metadata. This is option
* in setPtr, and is only invoked when either copying one metadata to
* another, or when the metadata is destroyed.
*
* setPtr(name, ptr, proc) {
* fPtr = proc(ptr, true);
* }
*
* copy: A = B {
* A.fPtr = B.fProc(B.fPtr, true);
* }
*
* ~SkMetaData {
* fProc(fPtr, false);
* }
*/
typedef void* (*PtrProc)(void* ptr, bool doRef);
/**
* Implements PtrProc for SkRefCnt pointers
*/
static void* RefCntProc(void* ptr, bool doRef);
SkMetaData();
SkMetaData(const SkMetaData& src);
~SkMetaData();
SkMetaData& operator=(const SkMetaData& src);
void reset();
bool findS32(const char name[], int32_t* value = nullptr) const;
bool findScalar(const char name[], SkScalar* value = nullptr) const;
const SkScalar* findScalars(const char name[], int* count,
SkScalar values[] = nullptr) const;
const char* findString(const char name[]) const;
bool findPtr(const char name[], void** value = nullptr, PtrProc* = nullptr) const;
bool findBool(const char name[], bool* value = nullptr) const;
const void* findData(const char name[], size_t* byteCount = nullptr) const;
bool hasS32(const char name[], int32_t value) const {
int32_t v;
return this->findS32(name, &v) && v == value;
}
bool hasScalar(const char name[], SkScalar value) const {
SkScalar v;
return this->findScalar(name, &v) && v == value;
}
bool hasString(const char name[], const char value[]) const {
const char* v = this->findString(name);
return (v == nullptr && value == nullptr) ||
(v != nullptr && value != nullptr && !strcmp(v, value));
}
bool hasPtr(const char name[], void* value) const {
void* v;
return this->findPtr(name, &v) && v == value;
}
bool hasBool(const char name[], bool value) const {
bool v;
return this->findBool(name, &v) && v == value;
}
bool hasData(const char name[], const void* data, size_t byteCount) const {
size_t len;
const void* ptr = this->findData(name, &len);
return ptr && len == byteCount && !memcmp(ptr, data, len);
}
void setS32(const char name[], int32_t value);
void setScalar(const char name[], SkScalar value);
SkScalar* setScalars(const char name[], int count, const SkScalar values[] = nullptr);
void setString(const char name[], const char value[]);
void setPtr(const char name[], void* value, PtrProc proc = nullptr);
void setBool(const char name[], bool value);
// the data is copied from the input pointer.
void setData(const char name[], const void* data, size_t byteCount);
bool removeS32(const char name[]);
bool removeScalar(const char name[]);
bool removeString(const char name[]);
bool removePtr(const char name[]);
bool removeBool(const char name[]);
bool removeData(const char name[]);
// helpers for SkRefCnt
bool findRefCnt(const char name[], SkRefCnt** ptr = nullptr) {
return this->findPtr(name, reinterpret_cast<void**>(ptr));
}
bool hasRefCnt(const char name[], SkRefCnt* ptr) {
return this->hasPtr(name, ptr);
}
void setRefCnt(const char name[], SkRefCnt* ptr) {
this->setPtr(name, ptr, RefCntProc);
}
bool removeRefCnt(const char name[]) {
return this->removePtr(name);
}
enum Type {
kS32_Type,
kScalar_Type,
kString_Type,
kPtr_Type,
kBool_Type,
kData_Type,
kTypeCount
};
struct Rec;
class Iter;
friend class Iter;
class Iter {
public:
Iter() : fRec(nullptr) {}
Iter(const SkMetaData&);
/** Reset the iterator, so that calling next() will return the first
data element. This is done implicitly in the constructor.
*/
void reset(const SkMetaData&);
/** Each time next is called, it returns the name of the next data element,
or null when there are no more elements. If non-null is returned, then the
element's type is returned (if not null), and the number of data values
is returned in count (if not null).
*/
const char* next(Type*, int* count);
private:
Rec* fRec;
};
public:
struct Rec {
Rec* fNext;
uint16_t fDataCount; // number of elements
uint8_t fDataLen; // sizeof a single element
uint8_t fType;
const void* data() const { return (this + 1); }
void* data() { return (this + 1); }
const char* name() const { return (const char*)this->data() + fDataLen * fDataCount; }
char* name() { return (char*)this->data() + fDataLen * fDataCount; }
static Rec* Alloc(size_t);
static void Free(Rec*);
};
Rec* fRec;
const Rec* find(const char name[], Type) const;
void* set(const char name[], const void* data, size_t len, Type, int count);
bool remove(const char name[], Type);
};
#endif

9
skia/include/core/SkMilestone.h vendored Normal file
View File

@ -0,0 +1,9 @@
/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SK_MILESTONE
#define SK_MILESTONE 72
#endif

75
skia/include/core/SkMultiPictureDraw.h vendored Normal file
View File

@ -0,0 +1,75 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkMultiPictureDraw_DEFINED
#define SkMultiPictureDraw_DEFINED
#include "../private/SkTDArray.h"
#include "SkMatrix.h"
class SkCanvas;
class SkPaint;
class SkPicture;
/** \class SkMultiPictureDraw
The MultiPictureDraw object accepts several picture/canvas pairs and
then attempts to optimally draw the pictures into the canvases, sharing
as many resources as possible.
*/
class SK_API SkMultiPictureDraw {
public:
/**
* Create an object to optimize the drawing of multiple pictures.
* @param reserve Hint for the number of add calls expected to be issued
*/
SkMultiPictureDraw(int reserve = 0);
~SkMultiPictureDraw() { this->reset(); }
/**
* Add a canvas/picture pair for later rendering.
* @param canvas the canvas in which to draw picture
* @param picture the picture to draw into canvas
* @param matrix if non-NULL, applied to the CTM when drawing
* @param paint if non-NULL, draw picture to a temporary buffer
* and then apply the paint when the result is drawn
*/
void add(SkCanvas* canvas,
const SkPicture* picture,
const SkMatrix* matrix = nullptr,
const SkPaint* paint = nullptr);
/**
* Perform all the previously added draws. This will reset the state
* of this object. If flush is true, all canvases are flushed after
* draw.
*/
void draw(bool flush = false);
/**
* Abandon all buffered draws and reset to the initial state.
*/
void reset();
private:
struct DrawData {
SkCanvas* fCanvas;
const SkPicture* fPicture; // reffed
SkMatrix fMatrix;
SkPaint* fPaint; // owned
void init(SkCanvas*, const SkPicture*, const SkMatrix*, const SkPaint*);
void draw();
static void Reset(SkTDArray<DrawData>&);
};
SkTDArray<DrawData> fThreadSafeDrawData;
SkTDArray<DrawData> fGPUDrawData;
};
#endif

74
skia/include/core/SkOverdrawCanvas.h vendored Normal file
View File

@ -0,0 +1,74 @@
/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkOverdrawCanvas_DEFINED
#define SkOverdrawCanvas_DEFINED
#include "SkCanvasVirtualEnforcer.h"
#include "SkNWayCanvas.h"
/**
* Captures all drawing commands. Rather than draw the actual content, this device
* increments the alpha channel of each pixel every time it would have been touched
* by a draw call. This is useful for detecting overdraw.
*/
class SK_API SkOverdrawCanvas : public SkCanvasVirtualEnforcer<SkNWayCanvas> {
public:
/* Does not take ownership of canvas */
SkOverdrawCanvas(SkCanvas*);
void onDrawText(const void*, size_t, SkScalar, SkScalar, const SkPaint&) override;
void onDrawPosText(const void*, size_t, const SkPoint[], const SkPaint&) override;
void onDrawPosTextH(const void*, size_t, const SkScalar[], SkScalar, const SkPaint&) override;
void onDrawTextRSXform(const void*, size_t, const SkRSXform[], const SkRect*,
const SkPaint&) override;
void onDrawTextBlob(const SkTextBlob*, SkScalar, SkScalar, const SkPaint&) override;
void onDrawPatch(const SkPoint[12], const SkColor[4], const SkPoint[4], SkBlendMode,
const SkPaint&) override;
void onDrawPaint(const SkPaint&) override;
void onDrawRect(const SkRect&, const SkPaint&) override;
void onDrawRegion(const SkRegion&, const SkPaint&) override;
void onDrawOval(const SkRect&, const SkPaint&) override;
void onDrawArc(const SkRect&, SkScalar, SkScalar, bool, const SkPaint&) override;
void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override;
void onDrawRRect(const SkRRect&, const SkPaint&) override;
void onDrawPoints(PointMode, size_t, const SkPoint[], const SkPaint&) override;
void onDrawVerticesObject(const SkVertices*, const SkVertices::Bone bones[], int boneCount,
SkBlendMode, const SkPaint&) override;
void onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[],
int, SkBlendMode, const SkRect*, const SkPaint*) override;
void onDrawPath(const SkPath&, const SkPaint&) override;
void onDrawImage(const SkImage*, SkScalar, SkScalar, const SkPaint*) override;
void onDrawImageRect(const SkImage*, const SkRect*, const SkRect&, const SkPaint*,
SrcRectConstraint) override;
void onDrawImageNine(const SkImage*, const SkIRect&, const SkRect&, const SkPaint*) override;
void onDrawImageLattice(const SkImage*, const Lattice&, const SkRect&, const SkPaint*) override;
void onDrawImageSet(const ImageSetEntry[], int count, SkFilterQuality, SkBlendMode) override;
void onDrawBitmap(const SkBitmap&, SkScalar, SkScalar, const SkPaint*) override;
void onDrawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&, const SkPaint*,
SrcRectConstraint) override;
void onDrawBitmapNine(const SkBitmap&, const SkIRect&, const SkRect&, const SkPaint*) override;
void onDrawBitmapLattice(const SkBitmap&, const Lattice&, const SkRect&,
const SkPaint*) override;
void onDrawDrawable(SkDrawable*, const SkMatrix*) override;
void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) override;
void onDrawAnnotation(const SkRect&, const char key[], SkData* value) override;
void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&) override;
private:
void drawPosTextCommon(const void*, size_t, const SkScalar[], int, const SkPoint&,
const SkPaint&);
inline SkPaint overdrawPaint(const SkPaint& paint);
SkPaint fPaint;
typedef SkCanvasVirtualEnforcer<SkNWayCanvas> INHERITED;
};
#endif

1427
skia/include/core/SkPaint.h vendored Normal file

File diff suppressed because it is too large Load Diff

1779
skia/include/core/SkPath.h vendored Normal file

File diff suppressed because it is too large Load Diff

187
skia/include/core/SkPathEffect.h vendored Normal file
View File

@ -0,0 +1,187 @@
/*
* Copyright 2006 The Android Open Source Project
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkPathEffect_DEFINED
#define SkPathEffect_DEFINED
#include "SkFlattenable.h"
#include "SkPath.h"
#include "SkPoint.h"
#include "SkRect.h"
class SkPath;
class SkStrokeRec;
/** \class SkPathEffect
SkPathEffect is the base class for objects in the SkPaint that affect
the geometry of a drawing primitive before it is transformed by the
canvas' matrix and drawn.
Dashing is implemented as a subclass of SkPathEffect.
*/
class SK_API SkPathEffect : public SkFlattenable {
public:
/**
* Returns a patheffect that apples each effect (first and second) to the original path,
* and returns a path with the sum of these.
*
* result = first(path) + second(path)
*
*/
static sk_sp<SkPathEffect> MakeSum(sk_sp<SkPathEffect> first, sk_sp<SkPathEffect> second);
/**
* Returns a patheffect that applies the inner effect to the path, and then applies the
* outer effect to the result of the inner's.
*
* result = outer(inner(path))
*/
static sk_sp<SkPathEffect> MakeCompose(sk_sp<SkPathEffect> outer, sk_sp<SkPathEffect> inner);
/**
* Given a src path (input) and a stroke-rec (input and output), apply
* this effect to the src path, returning the new path in dst, and return
* true. If this effect cannot be applied, return false and ignore dst
* and stroke-rec.
*
* The stroke-rec specifies the initial request for stroking (if any).
* The effect can treat this as input only, or it can choose to change
* the rec as well. For example, the effect can decide to change the
* stroke's width or join, or the effect can change the rec from stroke
* to fill (or fill to stroke) in addition to returning a new (dst) path.
*
* If this method returns true, the caller will apply (as needed) the
* resulting stroke-rec to dst and then draw.
*/
bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect* cullR) const;
/**
* Compute a conservative bounds for its effect, given the src bounds.
* The baseline implementation just assigns src to dst.
*/
void computeFastBounds(SkRect* dst, const SkRect& src) const;
/** \class PointData
PointData aggregates all the information needed to draw the point
primitives returned by an 'asPoints' call.
*/
class PointData {
public:
PointData()
: fFlags(0)
, fPoints(nullptr)
, fNumPoints(0) {
fSize.set(SK_Scalar1, SK_Scalar1);
// 'asPoints' needs to initialize/fill-in 'fClipRect' if it sets
// the kUseClip flag
}
~PointData() {
delete [] fPoints;
}
// TODO: consider using passed-in flags to limit the work asPoints does.
// For example, a kNoPath flag could indicate don't bother generating
// stamped solutions.
// Currently none of these flags are supported.
enum PointFlags {
kCircles_PointFlag = 0x01, // draw points as circles (instead of rects)
kUsePath_PointFlag = 0x02, // draw points as stamps of the returned path
kUseClip_PointFlag = 0x04, // apply 'fClipRect' before drawing the points
};
uint32_t fFlags; // flags that impact the drawing of the points
SkPoint* fPoints; // the center point of each generated point
int fNumPoints; // number of points in fPoints
SkVector fSize; // the size to draw the points
SkRect fClipRect; // clip required to draw the points (if kUseClip is set)
SkPath fPath; // 'stamp' to be used at each point (if kUsePath is set)
SkPath fFirst; // If not empty, contains geometry for first point
SkPath fLast; // If not empty, contains geometry for last point
};
/**
* Does applying this path effect to 'src' yield a set of points? If so,
* optionally return the points in 'results'.
*/
bool asPoints(PointData* results, const SkPath& src,
const SkStrokeRec&, const SkMatrix&,
const SkRect* cullR) const;
/**
* If the PathEffect can be represented as a dash pattern, asADash will return kDash_DashType
* and None otherwise. If a non NULL info is passed in, the various DashInfo will be filled
* in if the PathEffect can be a dash pattern. If passed in info has an fCount equal or
* greater to that of the effect, it will memcpy the values of the dash intervals into the
* info. Thus the general approach will be call asADash once with default info to get DashType
* and fCount. If effect can be represented as a dash pattern, allocate space for the intervals
* in info, then call asADash again with the same info and the intervals will get copied in.
*/
enum DashType {
kNone_DashType, //!< ignores the info parameter
kDash_DashType, //!< fills in all of the info parameter
};
struct DashInfo {
DashInfo() : fIntervals(nullptr), fCount(0), fPhase(0) {}
DashInfo(SkScalar* intervals, int32_t count, SkScalar phase)
: fIntervals(intervals), fCount(count), fPhase(phase) {}
SkScalar* fIntervals; //!< Length of on/off intervals for dashed lines
// Even values represent ons, and odds offs
int32_t fCount; //!< Number of intervals in the dash. Should be even number
SkScalar fPhase; //!< Offset into the dashed interval pattern
// mod the sum of all intervals
};
DashType asADash(DashInfo* info) const;
static void RegisterFlattenables();
static SkFlattenable::Type GetFlattenableType() {
return kSkPathEffect_Type;
}
SkFlattenable::Type getFlattenableType() const override {
return kSkPathEffect_Type;
}
static sk_sp<SkPathEffect> Deserialize(const void* data, size_t size,
const SkDeserialProcs* procs = nullptr) {
return sk_sp<SkPathEffect>(static_cast<SkPathEffect*>(
SkFlattenable::Deserialize(
kSkPathEffect_Type, data, size, procs).release()));
}
protected:
SkPathEffect() {}
virtual bool onFilterPath(SkPath*, const SkPath&, SkStrokeRec*, const SkRect*) const = 0;
virtual SkRect onComputeFastBounds(const SkRect& src) const {
return src;
}
virtual bool onAsPoints(PointData*, const SkPath&, const SkStrokeRec&, const SkMatrix&,
const SkRect*) const {
return false;
}
virtual DashType onAsADash(DashInfo*) const {
return kNone_DashType;
}
private:
// illegal
SkPathEffect(const SkPathEffect&);
SkPathEffect& operator=(const SkPathEffect&);
typedef SkFlattenable INHERITED;
};
#endif

125
skia/include/core/SkPathMeasure.h vendored Normal file
View File

@ -0,0 +1,125 @@
/*
* Copyright 2006 The Android Open Source Project
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkPathMeasure_DEFINED
#define SkPathMeasure_DEFINED
#include "../private/SkTDArray.h"
#include "SkPath.h"
struct SkConic;
class SK_API SkPathMeasure : SkNoncopyable {
public:
SkPathMeasure();
/** Initialize the pathmeasure with the specified path. The path must remain valid
for the lifetime of the measure object, or until setPath() is called with
a different path (or null), since the measure object keeps a pointer to the
path object (does not copy its data).
resScale controls the precision of the measure. values > 1 increase the
precision (and possible slow down the computation).
*/
SkPathMeasure(const SkPath& path, bool forceClosed, SkScalar resScale = 1);
~SkPathMeasure();
/** Reset the pathmeasure with the specified path. The path must remain valid
for the lifetime of the measure object, or until setPath() is called with
a different path (or null), since the measure object keeps a pointer to the
path object (does not copy its data).
*/
void setPath(const SkPath*, bool forceClosed);
/** Return the total length of the current contour, or 0 if no path
is associated (e.g. resetPath(null))
*/
SkScalar getLength();
/** Pins distance to 0 <= distance <= getLength(), and then computes
the corresponding position and tangent.
Returns false if there is no path, or a zero-length path was specified, in which case
position and tangent are unchanged.
*/
bool SK_WARN_UNUSED_RESULT getPosTan(SkScalar distance, SkPoint* position,
SkVector* tangent);
enum MatrixFlags {
kGetPosition_MatrixFlag = 0x01,
kGetTangent_MatrixFlag = 0x02,
kGetPosAndTan_MatrixFlag = kGetPosition_MatrixFlag | kGetTangent_MatrixFlag
};
/** Pins distance to 0 <= distance <= getLength(), and then computes
the corresponding matrix (by calling getPosTan).
Returns false if there is no path, or a zero-length path was specified, in which case
matrix is unchanged.
*/
bool SK_WARN_UNUSED_RESULT getMatrix(SkScalar distance, SkMatrix* matrix,
MatrixFlags flags = kGetPosAndTan_MatrixFlag);
/** Given a start and stop distance, return in dst the intervening segment(s).
If the segment is zero-length, return false, else return true.
startD and stopD are pinned to legal values (0..getLength()). If startD > stopD
then return false (and leave dst untouched).
Begin the segment with a moveTo if startWithMoveTo is true
*/
bool getSegment(SkScalar startD, SkScalar stopD, SkPath* dst, bool startWithMoveTo);
/** Return true if the current contour is closed()
*/
bool isClosed();
/** Move to the next contour in the path. Return true if one exists, or false if
we're done with the path.
*/
bool nextContour();
#ifdef SK_DEBUG
void dump();
#endif
private:
SkPath::Iter fIter;
SkPath fPath;
SkScalar fTolerance;
SkScalar fLength; // relative to the current contour
unsigned fFirstPtIndex; // relative to the current contour
bool fIsClosed; // relative to the current contour
bool fForceClosed;
#if defined(IS_FUZZING_WITH_LIBFUZZER)
int fSubdivisionsMax;
#endif
struct Segment {
SkScalar fDistance; // total distance up to this point
unsigned fPtIndex; // index into the fPts array
unsigned fTValue : 30;
unsigned fType : 2; // actually the enum SkSegType
// See SkPathMeasurePriv.h
SkScalar getScalarT() const;
};
SkTDArray<Segment> fSegments;
SkTDArray<SkPoint> fPts; // Points used to define the segments
static const Segment* NextSegment(const Segment*);
void buildSegments();
SkScalar compute_quad_segs(const SkPoint pts[3], SkScalar distance,
int mint, int maxt, unsigned ptIndex);
SkScalar compute_conic_segs(const SkConic&, SkScalar distance,
int mint, const SkPoint& minPt,
int maxt, const SkPoint& maxPt, unsigned ptIndex);
SkScalar compute_cubic_segs(const SkPoint pts[3], SkScalar distance,
int mint, int maxt, unsigned ptIndex);
const Segment* distanceToSegment(SkScalar distance, SkScalar* t);
bool quad_too_curvy(const SkPoint pts[3]);
bool conic_too_curvy(const SkPoint& firstPt, const SkPoint& midTPt,const SkPoint& lastPt);
bool cheap_dist_exceeds_limit(const SkPoint& pt, SkScalar x, SkScalar y);
bool cubic_too_curvy(const SkPoint pts[4]);
};
#endif

284
skia/include/core/SkPicture.h vendored Normal file
View File

@ -0,0 +1,284 @@
/*
* Copyright 2007 The Android Open Source Project
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/* Generated by tools/bookmaker from include/core/SkPicture.h and docs/SkPicture_Reference.bmh
on 2018-08-10 12:59:44. Additional documentation and examples can be found at:
https://skia.org/user/api/SkPicture_Reference
You may edit either file directly. Structural changes to public interfaces require
editing both files. After editing docs/SkPicture_Reference.bmh, run:
bookmaker -b docs -i include/core/SkPicture.h -p
to create an updated version of this file.
*/
#ifndef SkPicture_DEFINED
#define SkPicture_DEFINED
#include "SkRefCnt.h"
#include "SkRect.h"
#include "SkTypes.h"
class SkCanvas;
class SkData;
struct SkDeserialProcs;
class SkImage;
struct SkSerialProcs;
class SkStream;
class SkWStream;
/** \class SkPicture
SkPicture records drawing commands made to SkCanvas. The command stream may be
played in whole or in part at a later time.
SkPicture is an abstract class. SkPicture may be generated by SkPictureRecorder
or SkDrawable, or from SkPicture previously saved to SkData or SkStream.
SkPicture may contain any SkCanvas drawing command, as well as one or more
SkCanvas matrix or SkCanvas clip. SkPicture has a cull SkRect, which is used as
a bounding box hint. To limit SkPicture bounds, use SkCanvas clip when
recording or drawing SkPicture.
*/
class SK_API SkPicture : public SkRefCnt {
public:
/** Recreates SkPicture that was serialized into a stream. Returns constructed SkPicture
if successful; otherwise, returns nullptr. Fails if data does not permit
constructing valid SkPicture.
procs->fPictureProc permits supplying a custom function to decode SkPicture.
If procs->fPictureProc is nullptr, default decoding is used. procs->fPictureCtx
may be used to provide user context to procs->fPictureProc; procs->fPictureProc
is called with a pointer to data, data byte length, and user context.
@param stream container for serial data
@param procs custom serial data decoders; may be nullptr
@return SkPicture constructed from stream data
*/
static sk_sp<SkPicture> MakeFromStream(SkStream* stream,
const SkDeserialProcs* procs = nullptr);
/** Recreates SkPicture that was serialized into data. Returns constructed SkPicture
if successful; otherwise, returns nullptr. Fails if data does not permit
constructing valid SkPicture.
procs->fPictureProc permits supplying a custom function to decode SkPicture.
If procs->fPictureProc is nullptr, default decoding is used. procs->fPictureCtx
may be used to provide user context to procs->fPictureProc; procs->fPictureProc
is called with a pointer to data, data byte length, and user context.
@param data container for serial data
@param procs custom serial data decoders; may be nullptr
@return SkPicture constructed from data
*/
static sk_sp<SkPicture> MakeFromData(const SkData* data,
const SkDeserialProcs* procs = nullptr);
/**
@param data pointer to serial data
@param size size of data
@param procs custom serial data decoders; may be nullptr
@return SkPicture constructed from data
*/
static sk_sp<SkPicture> MakeFromData(const void* data, size_t size,
const SkDeserialProcs* procs = nullptr);
/** \class SkPicture::AbortCallback
AbortCallback is an abstract class. An implementation of AbortCallback may
passed as a parameter to SkPicture::playback, to stop it before all drawing
commands have been processed.
If AbortCallback::abort returns true, SkPicture::playback is interrupted.
*/
class SK_API AbortCallback {
public:
/** Has no effect.
@return abstract class cannot be instantiated
*/
AbortCallback() {}
/** Has no effect.
*/
virtual ~AbortCallback() {}
/** Stops SkPicture playback when some condition is met. A subclass of
AbortCallback provides an override for abort() that can stop SkPicture::playback.
The part of SkPicture drawn when aborted is undefined. SkPicture instantiations are
free to stop drawing at different points during playback.
If the abort happens inside one or more calls to SkCanvas::save(), stack
of SkCanvas matrix and SkCanvas clip values is restored to its state before
SkPicture::playback was called.
@return true to stop playback
*/
virtual bool abort() = 0;
};
/** Replays the drawing commands on the specified canvas. In the case that the
commands are recorded, each command in the SkPicture is sent separately to canvas.
To add a single command to draw SkPicture to recording canvas, call
SkCanvas::drawPicture instead.
@param canvas receiver of drawing commands
@param callback allows interruption of playback
*/
virtual void playback(SkCanvas* canvas, AbortCallback* callback = nullptr) const = 0;
/** Returns cull SkRect for this picture, passed in when SkPicture was created.
Returned SkRect does not specify clipping SkRect for SkPicture; cull is hint
of SkPicture bounds.
SkPicture is free to discard recorded drawing commands that fall outside
cull.
@return bounds passed when SkPicture was created
*/
virtual SkRect cullRect() const = 0;
/** Returns a non-zero value unique among SkPicture in Skia process.
@return identifier for SkPicture
*/
uint32_t uniqueID() const;
/** Returns storage containing SkData describing SkPicture, using optional custom
encoders.
procs->fPictureProc permits supplying a custom function to encode SkPicture.
If procs->fPictureProc is nullptr, default encoding is used. procs->fPictureCtx
may be used to provide user context to procs->fPictureProc; procs->fPictureProc
is called with a pointer to SkPicture and user context.
@param procs custom serial data encoders; may be nullptr
@return storage containing serialized SkPicture
*/
sk_sp<SkData> serialize(const SkSerialProcs* procs = nullptr) const;
/** Writes picture to stream, using optional custom encoders.
procs->fPictureProc permits supplying a custom function to encode SkPicture.
If procs->fPictureProc is nullptr, default encoding is used. procs->fPictureCtx
may be used to provide user context to procs->fPictureProc; procs->fPictureProc
is called with a pointer to SkPicture and user context.
@param stream writable serial data stream
@param procs custom serial data encoders; may be nullptr
*/
void serialize(SkWStream* stream, const SkSerialProcs* procs = nullptr) const;
/** Returns a placeholder SkPicture. Result does not draw, and contains only
cull SkRect, a hint of its bounds. Result is immutable; it cannot be changed
later. Result identifier is unique.
Returned placeholder can be intercepted during playback to insert other
commands into SkCanvas draw stream.
@param cull placeholder dimensions
@return placeholder with unique identifier
*/
static sk_sp<SkPicture> MakePlaceholder(SkRect cull);
/** Returns the approximate number of operations in SkPicture. Returned value
may be greater or less than the number of SkCanvas calls
recorded: some calls may be recorded as more than one operation, other
calls may be optimized away.
@return approximate operation count
*/
virtual int approximateOpCount() const = 0;
/** Returns the approximate byte size of SkPicture. Does not include large objects
referenced by SkPicture.
@return approximate size
*/
virtual size_t approximateBytesUsed() const = 0;
private:
// Subclass whitelist.
SkPicture();
friend class SkBigPicture;
friend class SkEmptyPicture;
friend class SkPicturePriv;
template <typename> friend class SkMiniPicture;
void serialize(SkWStream*, const SkSerialProcs*, class SkRefCntSet* typefaces) const;
static sk_sp<SkPicture> MakeFromStream(SkStream*, const SkDeserialProcs*,
class SkTypefacePlayback*);
friend class SkPictureData;
/** Return true if the SkStream/Buffer represents a serialized picture, and
fills out SkPictInfo. After this function returns, the data source is not
rewound so it will have to be manually reset before passing to
MakeFromStream or MakeFromBuffer. Note, MakeFromStream and
MakeFromBuffer perform this check internally so these entry points are
intended for stand alone tools.
If false is returned, SkPictInfo is unmodified.
*/
static bool StreamIsSKP(SkStream*, struct SkPictInfo*);
static bool BufferIsSKP(class SkReadBuffer*, struct SkPictInfo*);
friend bool SkPicture_StreamIsSKP(SkStream*, struct SkPictInfo*);
// Returns NULL if this is not an SkBigPicture.
virtual const class SkBigPicture* asSkBigPicture() const { return nullptr; }
friend struct SkPathCounter;
// V35: Store SkRect (rather then width & height) in header
// V36: Remove (obsolete) alphatype from SkColorTable
// V37: Added shadow only option to SkDropShadowImageFilter (last version to record CLEAR)
// V38: Added PictureResolution option to SkPictureImageFilter
// V39: Added FilterLevel option to SkPictureImageFilter
// V40: Remove UniqueID serialization from SkImageFilter.
// V41: Added serialization of SkBitmapSource's filterQuality parameter
// V42: Added a bool to SkPictureShader serialization to indicate did-we-serialize-a-picture?
// V43: Added DRAW_IMAGE and DRAW_IMAGE_RECT opt codes to serialized data
// V44: Move annotations from paint to drawAnnotation
// V45: Add invNormRotation to SkLightingShader.
// V46: Add drawTextRSXform
// V47: Add occluder rect to SkBlurMaskFilter
// V48: Read and write extended SkTextBlobs.
// V49: Gradients serialized as SkColor4f + SkColorSpace
// V50: SkXfermode -> SkBlendMode
// V51: more SkXfermode -> SkBlendMode
// V52: Remove SkTextBlob::fRunCount
// V53: SaveLayerRec clip mask
// V54: ComposeShader can use a Mode or a Lerp
// V55: Drop blendmode[] from MergeImageFilter
// V56: Add TileMode in SkBlurImageFilter.
// V57: Sweep tiling info.
// V58: No more 2pt conical flipping.
// V59: No more LocalSpace option on PictureImageFilter
// V60: Remove flags in picture header
// V61: Change SkDrawPictureRec to take two colors rather than two alphas
// V62: Don't negate size of custom encoded images (don't write origin x,y either)
// V63: Store image bounds (including origin) instead of just width/height to support subsets
// V64: Remove occluder feature from blur maskFilter
// Only SKPs within the min/current picture version range (inclusive) can be read.
static const uint32_t MIN_PICTURE_VERSION = 56; // august 2017
static const uint32_t CURRENT_PICTURE_VERSION = 65;
static_assert(MIN_PICTURE_VERSION <= 62, "Remove kFontAxes_bad from SkFontDescriptor.cpp");
static bool IsValidPictInfo(const struct SkPictInfo& info);
static sk_sp<SkPicture> Forwardport(const struct SkPictInfo&,
const class SkPictureData*,
class SkReadBuffer* buffer);
struct SkPictInfo createHeader() const;
class SkPictureData* backport() const;
mutable uint32_t fUniqueID;
};
#endif

125
skia/include/core/SkPictureRecorder.h vendored Normal file
View File

@ -0,0 +1,125 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkPictureRecorder_DEFINED
#define SkPictureRecorder_DEFINED
#include "../private/SkNoncopyable.h"
#include "SkBBHFactory.h"
#include "SkPicture.h"
#include "SkRefCnt.h"
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
namespace android {
class Picture;
};
#endif
class GrContext;
class SkCanvas;
class SkDrawable;
class SkMiniRecorder;
class SkPictureRecord;
class SkRecord;
class SkRecorder;
class SK_API SkPictureRecorder : SkNoncopyable {
public:
SkPictureRecorder();
~SkPictureRecorder();
enum RecordFlags {
// If you call drawPicture() or drawDrawable() on the recording canvas, this flag forces
// that object to playback its contents immediately rather than reffing the object.
kPlaybackDrawPicture_RecordFlag = 1 << 0,
};
enum FinishFlags {
};
/** Returns the canvas that records the drawing commands.
@param bounds the cull rect used when recording this picture. Any drawing the falls outside
of this rect is undefined, and may be drawn or it may not.
@param bbhFactory factory to create desired acceleration structure
@param recordFlags optional flags that control recording.
@return the canvas.
*/
SkCanvas* beginRecording(const SkRect& bounds,
SkBBHFactory* bbhFactory = nullptr,
uint32_t recordFlags = 0);
SkCanvas* beginRecording(SkScalar width, SkScalar height,
SkBBHFactory* bbhFactory = nullptr,
uint32_t recordFlags = 0) {
return this->beginRecording(SkRect::MakeWH(width, height), bbhFactory, recordFlags);
}
/** Returns the recording canvas if one is active, or NULL if recording is
not active. This does not alter the refcnt on the canvas (if present).
*/
SkCanvas* getRecordingCanvas();
/**
* Signal that the caller is done recording. This invalidates the canvas returned by
* beginRecording/getRecordingCanvas. Ownership of the object is passed to the caller, who
* must call unref() when they are done using it.
*
* The returned picture is immutable. If during recording drawables were added to the canvas,
* these will have been "drawn" into a recording canvas, so that this resulting picture will
* reflect their current state, but will not contain a live reference to the drawables
* themselves.
*/
sk_sp<SkPicture> finishRecordingAsPicture(uint32_t endFlags = 0);
/**
* Signal that the caller is done recording, and update the cull rect to use for bounding
* box hierarchy (BBH) generation. The behavior is the same as calling
* finishRecordingAsPicture(), except that this method updates the cull rect initially passed
* into beginRecording.
* @param cullRect the new culling rectangle to use as the overall bound for BBH generation
* and subsequent culling operations.
* @return the picture containing the recorded content.
*/
sk_sp<SkPicture> finishRecordingAsPictureWithCull(const SkRect& cullRect,
uint32_t endFlags = 0);
/**
* Signal that the caller is done recording. This invalidates the canvas returned by
* beginRecording/getRecordingCanvas. Ownership of the object is passed to the caller, who
* must call unref() when they are done using it.
*
* Unlike finishRecordingAsPicture(), which returns an immutable picture, the returned drawable
* may contain live references to other drawables (if they were added to the recording canvas)
* and therefore this drawable will reflect the current state of those nested drawables anytime
* it is drawn or a new picture is snapped from it (by calling drawable->newPictureSnapshot()).
*/
sk_sp<SkDrawable> finishRecordingAsDrawable(uint32_t endFlags = 0);
private:
void reset();
/** Replay the current (partially recorded) operation stream into
canvas. This call doesn't close the current recording.
*/
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
friend class android::Picture;
#endif
friend class SkPictureRecorderReplayTester; // for unit testing
void partialReplay(SkCanvas* canvas) const;
bool fActivelyRecording;
uint32_t fFlags;
SkRect fCullRect;
sk_sp<SkBBoxHierarchy> fBBH;
std::unique_ptr<SkRecorder> fRecorder;
sk_sp<SkRecord> fRecord;
std::unique_ptr<SkMiniRecorder> fMiniRecorder;
typedef SkNoncopyable INHERITED;
};
#endif

129
skia/include/core/SkPixelRef.h vendored Normal file
View File

@ -0,0 +1,129 @@
/*
* 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 SkPixelRef_DEFINED
#define SkPixelRef_DEFINED
#include "../private/SkMutex.h"
#include "../private/SkTDArray.h"
#include "SkBitmap.h"
#include "SkFilterQuality.h"
#include "SkImageInfo.h"
#include "SkPixmap.h"
#include "SkRefCnt.h"
#include "SkSize.h"
#include "SkString.h"
#include <atomic>
struct SkIRect;
class GrTexture;
class SkDiscardableMemory;
/** \class SkPixelRef
This class is the smart container for pixel memory, and is used with SkBitmap.
This class can be shared/accessed between multiple threads.
*/
class SK_API SkPixelRef : public SkRefCnt {
public:
SkPixelRef(int width, int height, void* addr, size_t rowBytes);
~SkPixelRef() override;
int width() const { return fWidth; }
int height() const { return fHeight; }
void* pixels() const { return fPixels; }
size_t rowBytes() const { return fRowBytes; }
/** Returns a non-zero, unique value corresponding to the pixels in this
pixelref. Each time the pixels are changed (and notifyPixelsChanged is
called), a different generation ID will be returned.
*/
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().
*/
void notifyPixelsChanged();
/** 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.
*/
bool isImmutable() const { return fMutability != kMutable; }
/** Marks this pixelref is immutable, meaning that the contents of its
pixels will not change for the lifetime of the pixelref. This state can
be set on a pixelref, but it cannot be cleared once it is set.
*/
void setImmutable();
// 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. Threadsafe.
void addGenIDChangeListener(GenIDChangeListener* listener);
// Call when this pixelref is part of the key to a resourcecache entry. This allows the cache
// to know automatically those entries can be purged when this pixelref is changed or deleted.
void notifyAddedToCache() {
fAddedToCache.store(true);
}
virtual SkDiscardableMemory* diagnostic_only_getDiscardable() const { return nullptr; }
protected:
void android_only_reset(int width, int height, size_t rowBytes);
private:
int fWidth;
int fHeight;
void* fPixels;
size_t fRowBytes;
// Bottom bit indicates the Gen ID is unique.
bool genIDIsUnique() const { return SkToBool(fTaggedGenID.load() & 1); }
mutable std::atomic<uint32_t> fTaggedGenID;
SkMutex fGenIDChangeListenersMutex;
SkTDArray<GenIDChangeListener*> fGenIDChangeListeners; // pointers are owned
// Set true by caches when they cache content that's derived from the current pixels.
std::atomic<bool> fAddedToCache;
enum Mutability {
kMutable, // PixelRefs begin mutable.
kTemporarilyImmutable, // Considered immutable, but can revert to mutable.
kImmutable, // Once set to this state, it never leaves.
} fMutability : 8; // easily fits inside a byte
void needsNewGenID();
void callGenIDChangeListeners();
void setTemporarilyImmutable();
void restoreMutability();
friend class SkSurface_Raster; // For the two methods above.
void setImmutableWithID(uint32_t genID);
friend void SkBitmapCache_setImmutableWithID(SkPixelRef*, uint32_t);
typedef SkRefCnt INHERITED;
};
#endif

706
skia/include/core/SkPixmap.h vendored Normal file
View File

@ -0,0 +1,706 @@
/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/* Generated by tools/bookmaker from include/core/SkPixmap.h and docs/SkPixmap_Reference.bmh
on 2018-06-08 11:48:28. Additional documentation and examples can be found at:
https://skia.org/user/api/SkPixmap_Reference
You may edit either file directly. Structural changes to public interfaces require
editing both files. After editing docs/SkPixmap_Reference.bmh, run:
bookmaker -b docs -i include/core/SkPixmap.h -p
to create an updated version of this file.
*/
#ifndef SkPixmap_DEFINED
#define SkPixmap_DEFINED
#include "SkColor.h"
#include "SkFilterQuality.h"
#include "SkImageInfo.h"
class SkData;
struct SkMask;
/** \class SkPixmap
SkPixmap provides a utility to pair SkImageInfo with pixels and row bytes.
SkPixmap is a low level class which provides convenience functions to access
raster destinations. SkCanvas can not draw SkPixmap, nor does SkPixmap provide
a direct drawing destination.
Use SkBitmap to draw pixels referenced by SkPixmap; use SkSurface to draw into
pixels referenced by SkPixmap.
SkPixmap does not try to manage the lifetime of the pixel memory. Use SkPixelRef
to manage pixel memory; SkPixelRef is safe across threads.
*/
class SK_API SkPixmap {
public:
/** Creates an empty SkPixmap without pixels, with kUnknown_SkColorType, with
kUnknown_SkAlphaType, and with a width and height of zero. Use
reset() to associate pixels, SkColorType, SkAlphaType, width, and height
after SkPixmap has been created.
@return empty SkPixmap
*/
SkPixmap()
: fPixels(nullptr), fRowBytes(0), fInfo(SkImageInfo::MakeUnknown(0, 0))
{}
/** Creates SkPixmap from info width, height, SkAlphaType, and SkColorType.
addr points to pixels, or nullptr. rowBytes should be info.width() times
info.bytesPerPixel(), or larger.
No parameter checking is performed; it is up to the caller to ensure that
addr and rowBytes agree with info.
The memory lifetime of pixels is managed by the caller. When SkPixmap goes
out of scope, addr is unaffected.
SkPixmap may be later modified by reset() to change its size, pixel type, or
storage.
@param info width, height, SkAlphaType, SkColorType of SkImageInfo
@param addr pointer to pixels allocated by caller; may be nullptr
@param rowBytes size of one row of addr; width times pixel size, or larger
@return initialized SkPixmap
*/
SkPixmap(const SkImageInfo& info, const void* addr, size_t rowBytes)
: fPixels(addr), fRowBytes(rowBytes), fInfo(info)
{}
/** Sets width, height, row bytes to zero; pixel address to nullptr; SkColorType to
kUnknown_SkColorType; and SkAlphaType to kUnknown_SkAlphaType.
The prior pixels are unaffected; it is up to the caller to release pixels
memory if desired.
*/
void reset();
/** Sets width, height, SkAlphaType, and SkColorType from info.
Sets pixel address from addr, which may be nullptr.
Sets row bytes from rowBytes, which should be info.width() times
info.bytesPerPixel(), or larger.
Does not check addr. Asserts if built with SK_DEBUG defined and if rowBytes is
too small to hold one row of pixels.
The memory lifetime pixels are managed by the caller. When SkPixmap goes
out of scope, addr is unaffected.
@param info width, height, SkAlphaType, SkColorType of SkImageInfo
@param addr pointer to pixels allocated by caller; may be nullptr
@param rowBytes size of one row of addr; width times pixel size, or larger
*/
void reset(const SkImageInfo& info, const void* addr, size_t rowBytes);
/** Changes SkColorSpace in SkImageInfo; preserves width, height, SkAlphaType, and
SkColorType in SkImage, and leaves pixel address and row bytes unchanged.
SkColorSpace reference count is incremented.
@param colorSpace SkColorSpace moved to SkImageInfo
*/
void setColorSpace(sk_sp<SkColorSpace> colorSpace);
/** Deprecated.
*/
bool SK_WARN_UNUSED_RESULT reset(const SkMask& mask);
/** Sets subset width, height, pixel address to intersection of SkPixmap with area,
if intersection is not empty; and return true. Otherwise, leave subset unchanged
and return false.
Failing to read the return value generates a compile time warning.
@param subset storage for width, height, pixel address of intersection
@param area bounds to intersect with SkPixmap
@return true if intersection of SkPixmap and area is not empty
*/
bool SK_WARN_UNUSED_RESULT extractSubset(SkPixmap* subset, const SkIRect& area) const;
/** Returns width, height, SkAlphaType, SkColorType, and SkColorSpace.
@return reference to SkImageInfo
*/
const SkImageInfo& info() const { return fInfo; }
/** Returns row bytes, the interval from one pixel row to the next. Row bytes
is at least as large as: width() * info().bytesPerPixel().
Returns zero if colorType() is kUnknown_SkColorType.
It is up to the SkBitmap creator to ensure that row bytes is a useful value.
@return byte length of pixel row
*/
size_t rowBytes() const { return fRowBytes; }
/** Returns pixel address, the base address corresponding to the pixel origin.
It is up to the SkPixmap creator to ensure that pixel address is a useful value.
@return pixel address
*/
const void* addr() const { return fPixels; }
/** Returns pixel count in each pixel row. Should be equal or less than:
rowBytes() / info().bytesPerPixel().
@return pixel width in SkImageInfo
*/
int width() const { return fInfo.width(); }
/** Returns pixel row count.
@return pixel height in SkImageInfo
*/
int height() const { return fInfo.height(); }
/** Returns SkColorType, one of:
kUnknown_SkColorType, kAlpha_8_SkColorType, kRGB_565_SkColorType,
kARGB_4444_SkColorType, kRGBA_8888_SkColorType, kRGB_888x_SkColorType,
kBGRA_8888_SkColorType, kRGBA_1010102_SkColorType, kRGB_101010x_SkColorType,
kGray_8_SkColorType, kRGBA_F16_SkColorType.
@return SkColorType in SkImageInfo
*/
SkColorType colorType() const { return fInfo.colorType(); }
/** Returns SkAlphaType, one of:
kUnknown_SkAlphaType, kOpaque_SkAlphaType, kPremul_SkAlphaType,
kUnpremul_SkAlphaType.
@return SkAlphaType in SkImageInfo
*/
SkAlphaType alphaType() const { return fInfo.alphaType(); }
/** Returns SkColorSpace, the range of colors, associated with SkImageInfo. The
reference count of SkColorSpace is unchanged. The returned SkColorSpace is
immutable.
@return SkColorSpace in SkImageInfo, or nullptr
*/
SkColorSpace* colorSpace() const { return fInfo.colorSpace(); }
/** Returns true if SkAlphaType is kOpaque_SkAlphaType.
Does not check if SkColorType allows alpha, or if any pixel value has
transparency.
@return true if SkImageInfo has opaque SkAlphaType
*/
bool isOpaque() const { return fInfo.isOpaque(); }
/** Returns SkIRect { 0, 0, width(), height() }.
@return integral rectangle from origin to width() and height()
*/
SkIRect bounds() const { return SkIRect::MakeWH(this->width(), this->height()); }
/** Returns number of pixels that fit on row. Should be greater than or equal to
width().
@return maximum pixels per row
*/
int rowBytesAsPixels() const { return int(fRowBytes >> this->shiftPerPixel()); }
/** Returns bit shift converting row bytes to row pixels.
Returns zero for kUnknown_SkColorType.
@return one of: 0, 1, 2, 3; left shift to convert pixels to bytes
*/
int shiftPerPixel() const { return fInfo.shiftPerPixel(); }
/** Returns minimum memory required for pixel storage.
Does not include unused memory on last row when rowBytesAsPixels() exceeds width().
Returns zero if result does not fit in size_t.
Returns zero if height() or width() is 0.
Returns height() times rowBytes() if colorType() is kUnknown_SkColorType.
@return size in bytes of image buffer
*/
size_t computeByteSize() const { return fInfo.computeByteSize(fRowBytes); }
/** Returns true if all pixels are opaque. SkColorType determines how pixels
are encoded, and whether pixel describes alpha. Returns true for SkColorType
without alpha in each pixel; for other SkColorType, returns true if all
pixels have alpha values equivalent to 1.0 or greater.
For SkColorType kRGB_565_SkColorType or kGray_8_SkColorType: always
returns true. For SkColorType kAlpha_8_SkColorType, kBGRA_8888_SkColorType,
kRGBA_8888_SkColorType: returns true if all pixel alpha values are 255.
For SkColorType kARGB_4444_SkColorType: returns true if all pixel alpha values are 15.
For kRGBA_F16_SkColorType: returns true if all pixel alpha values are 1.0 or
greater.
Returns false for kUnknown_SkColorType.
@return true if all pixels have opaque values or SkColorType is opaque
*/
bool computeIsOpaque() const;
/** Returns pixel at (x, y) as unpremultiplied color.
Returns black with alpha if SkColorType is kAlpha_8_SkColorType.
Input is not validated: out of bounds values of x or y trigger an assert() if
built with SK_DEBUG defined; and returns undefined values or may crash if
SK_RELEASE is defined. Fails if SkColorType is kUnknown_SkColorType or
pixel address is nullptr.
SkColorSpace in SkImageInfo is ignored. Some color precision may be lost in the
conversion to unpremultiplied color; original pixel data may have additional
precision.
@param x column index, zero or greater, and less than width()
@param y row index, zero or greater, and less than height()
@return pixel converted to unpremultiplied color
*/
SkColor getColor(int x, int y) const;
/** Look up the pixel at (x,y) and return its alpha component, normalized to [0..1].
This is roughly equivalent to SkGetColorA(getColor()), but can be more efficent
(and more precise if the pixels store more than 8 bits per component).
@param x column index, zero or greater, and less than width()
@param y row index, zero or greater, and less than height()
@return alpha converted to normalized float
*/
float getAlphaf(int x, int y) const;
/** Returns readable pixel address at (x, y). Returns nullptr if SkPixelRef is nullptr.
Input is not validated: out of bounds values of x or y trigger an assert() if
built with SK_DEBUG defined. Returns nullptr if SkColorType is kUnknown_SkColorType.
Performs a lookup of pixel size; for better performance, call
one of: addr8, addr16, addr32, addr64, or addrF16().
@param x column index, zero or greater, and less than width()
@param y row index, zero or greater, and less than height()
@return readable generic pointer to pixel
*/
const void* addr(int x, int y) const {
return (const char*)fPixels + fInfo.computeOffset(x, y, fRowBytes);
}
/** Returns readable base pixel address. Result is addressable as unsigned 8-bit bytes.
Will trigger an assert() if SkColorType is not kAlpha_8_SkColorType or
kGray_8_SkColorType, and is built with SK_DEBUG defined.
One byte corresponds to one pixel.
@return readable unsigned 8-bit pointer to pixels
*/
const uint8_t* addr8() const {
SkASSERT(1 == fInfo.bytesPerPixel());
return reinterpret_cast<const uint8_t*>(fPixels);
}
/** Returns readable base pixel address. Result is addressable as unsigned 16-bit words.
Will trigger an assert() if SkColorType is not kRGB_565_SkColorType or
kARGB_4444_SkColorType, and is built with SK_DEBUG defined.
One word corresponds to one pixel.
@return readable unsigned 16-bit pointer to pixels
*/
const uint16_t* addr16() const {
SkASSERT(2 == fInfo.bytesPerPixel());
return reinterpret_cast<const uint16_t*>(fPixels);
}
/** Returns readable base pixel address. Result is addressable as unsigned 32-bit words.
Will trigger an assert() if SkColorType is not kRGBA_8888_SkColorType or
kBGRA_8888_SkColorType, and is built with SK_DEBUG defined.
One word corresponds to one pixel.
@return readable unsigned 32-bit pointer to pixels
*/
const uint32_t* addr32() const {
SkASSERT(4 == fInfo.bytesPerPixel());
return reinterpret_cast<const uint32_t*>(fPixels);
}
/** Returns readable base pixel address. Result is addressable as unsigned 64-bit words.
Will trigger an assert() if SkColorType is not kRGBA_F16_SkColorType and is built
with SK_DEBUG defined.
One word corresponds to one pixel.
@return readable unsigned 64-bit pointer to pixels
*/
const uint64_t* addr64() const {
SkASSERT(8 == fInfo.bytesPerPixel());
return reinterpret_cast<const uint64_t*>(fPixels);
}
/** Returns readable base pixel address. Result is addressable as unsigned 16-bit words.
Will trigger an assert() if SkColorType is not kRGBA_F16_SkColorType and is built
with SK_DEBUG defined.
Each word represents one color component encoded as a half float.
Four words correspond to one pixel.
@return readable unsigned 16-bit pointer to first component of pixels
*/
const uint16_t* addrF16() const {
SkASSERT(8 == fInfo.bytesPerPixel());
SkASSERT(kRGBA_F16_SkColorType == fInfo.colorType());
return reinterpret_cast<const uint16_t*>(fPixels);
}
/** Returns readable pixel address at (x, y).
Input is not validated: out of bounds values of x or y trigger an assert() if
built with SK_DEBUG defined.
Will trigger an assert() if SkColorType is not kAlpha_8_SkColorType or
kGray_8_SkColorType, and is built with SK_DEBUG defined.
@param x column index, zero or greater, and less than width()
@param y row index, zero or greater, and less than height()
@return readable unsigned 8-bit pointer to pixel at (x, y)
*/
const uint8_t* addr8(int x, int y) const {
SkASSERT((unsigned)x < (unsigned)fInfo.width());
SkASSERT((unsigned)y < (unsigned)fInfo.height());
return (const uint8_t*)((const char*)this->addr8() + y * fRowBytes + (x << 0));
}
/** Returns readable pixel address at (x, y).
Input is not validated: out of bounds values of x or y trigger an assert() if
built with SK_DEBUG defined.
Will trigger an assert() if SkColorType is not kRGB_565_SkColorType or
kARGB_4444_SkColorType, and is built with SK_DEBUG defined.
@param x column index, zero or greater, and less than width()
@param y row index, zero or greater, and less than height()
@return readable unsigned 16-bit pointer to pixel at (x, y)
*/
const uint16_t* addr16(int x, int y) const {
SkASSERT((unsigned)x < (unsigned)fInfo.width());
SkASSERT((unsigned)y < (unsigned)fInfo.height());
return (const uint16_t*)((const char*)this->addr16() + y * fRowBytes + (x << 1));
}
/** Returns readable pixel address at (x, y).
Input is not validated: out of bounds values of x or y trigger an assert() if
built with SK_DEBUG defined.
Will trigger an assert() if SkColorType is not kRGBA_8888_SkColorType or
kBGRA_8888_SkColorType, and is built with SK_DEBUG defined.
@param x column index, zero or greater, and less than width()
@param y row index, zero or greater, and less than height()
@return readable unsigned 32-bit pointer to pixel at (x, y)
*/
const uint32_t* addr32(int x, int y) const {
SkASSERT((unsigned)x < (unsigned)fInfo.width());
SkASSERT((unsigned)y < (unsigned)fInfo.height());
return (const uint32_t*)((const char*)this->addr32() + y * fRowBytes + (x << 2));
}
/** Returns readable pixel address at (x, y).
Input is not validated: out of bounds values of x or y trigger an assert() if
built with SK_DEBUG defined.
Will trigger an assert() if SkColorType is not kRGBA_F16_SkColorType and is built
with SK_DEBUG defined.
@param x column index, zero or greater, and less than width()
@param y row index, zero or greater, and less than height()
@return readable unsigned 64-bit pointer to pixel at (x, y)
*/
const uint64_t* addr64(int x, int y) const {
SkASSERT((unsigned)x < (unsigned)fInfo.width());
SkASSERT((unsigned)y < (unsigned)fInfo.height());
return (const uint64_t*)((const char*)this->addr64() + y * fRowBytes + (x << 3));
}
/** Returns readable pixel address at (x, y).
Input is not validated: out of bounds values of x or y trigger an assert() if
built with SK_DEBUG defined.
Will trigger an assert() if SkColorType is not kRGBA_F16_SkColorType and is built
with SK_DEBUG defined.
Each unsigned 16-bit word represents one color component encoded as a half float.
Four words correspond to one pixel.
@param x column index, zero or greater, and less than width()
@param y row index, zero or greater, and less than height()
@return readable unsigned 16-bit pointer to pixel component at (x, y)
*/
const uint16_t* addrF16(int x, int y) const {
SkASSERT(kRGBA_F16_SkColorType == fInfo.colorType());
return reinterpret_cast<const uint16_t*>(this->addr64(x, y));
}
/** Returns writable base pixel address.
@return writable generic base pointer to pixels
*/
void* writable_addr() const { return const_cast<void*>(fPixels); }
/** Returns writable pixel address at (x, y).
Input is not validated: out of bounds values of x or y trigger an assert() if
built with SK_DEBUG defined. Returns zero if SkColorType is kUnknown_SkColorType.
@param x column index, zero or greater, and less than width()
@param y row index, zero or greater, and less than height()
@return writable generic pointer to pixel
*/
void* writable_addr(int x, int y) const {
return const_cast<void*>(this->addr(x, y));
}
/** Returns writable pixel address at (x, y). Result is addressable as unsigned
8-bit bytes. Will trigger an assert() if SkColorType is not kAlpha_8_SkColorType
or kGray_8_SkColorType, and is built with SK_DEBUG defined.
One byte corresponds to one pixel.
@param x column index, zero or greater, and less than width()
@param y row index, zero or greater, and less than height()
@return writable unsigned 8-bit pointer to pixels
*/
uint8_t* writable_addr8(int x, int y) const {
return const_cast<uint8_t*>(this->addr8(x, y));
}
/** Returns writable_addr pixel address at (x, y). Result is addressable as unsigned
16-bit words. Will trigger an assert() if SkColorType is not kRGB_565_SkColorType
or kARGB_4444_SkColorType, and is built with SK_DEBUG defined.
One word corresponds to one pixel.
@param x column index, zero or greater, and less than width()
@param y row index, zero or greater, and less than height()
@return writable unsigned 16-bit pointer to pixel
*/
uint16_t* writable_addr16(int x, int y) const {
return const_cast<uint16_t*>(this->addr16(x, y));
}
/** Returns writable pixel address at (x, y). Result is addressable as unsigned
32-bit words. Will trigger an assert() if SkColorType is not
kRGBA_8888_SkColorType or kBGRA_8888_SkColorType, and is built with SK_DEBUG
defined.
One word corresponds to one pixel.
@param x column index, zero or greater, and less than width()
@param y row index, zero or greater, and less than height()
@return writable unsigned 32-bit pointer to pixel
*/
uint32_t* writable_addr32(int x, int y) const {
return const_cast<uint32_t*>(this->addr32(x, y));
}
/** Returns writable pixel address at (x, y). Result is addressable as unsigned
64-bit words. Will trigger an assert() if SkColorType is not
kRGBA_F16_SkColorType and is built with SK_DEBUG defined.
One word corresponds to one pixel.
@param x column index, zero or greater, and less than width()
@param y row index, zero or greater, and less than height()
@return writable unsigned 64-bit pointer to pixel
*/
uint64_t* writable_addr64(int x, int y) const {
return const_cast<uint64_t*>(this->addr64(x, y));
}
/** Returns writable pixel address at (x, y). Result is addressable as unsigned
16-bit words. Will trigger an assert() if SkColorType is not
kRGBA_F16_SkColorType and is built with SK_DEBUG defined.
Each word represents one color component encoded as a half float.
Four words correspond to one pixel.
@param x column index, zero or greater, and less than width()
@param y row index, zero or greater, and less than height()
@return writable unsigned 16-bit pointer to first component of pixel
*/
uint16_t* writable_addrF16(int x, int y) const {
return reinterpret_cast<uint16_t*>(writable_addr64(x, y));
}
/** Copies a SkRect of pixels to dstPixels. Copy starts at (0, 0), and does not
exceed SkPixmap (width(), height()).
dstInfo specifies width, height, SkColorType, SkAlphaType, and
SkColorSpace of destination. dstRowBytes specifics the gap from one destination
row to the next. Returns true if pixels are copied. Returns false if
dstInfo address equals nullptr, or dstRowBytes is less than dstInfo.minRowBytes().
Pixels are copied only if pixel conversion is possible. If SkPixmap colorType() is
kGray_8_SkColorType, or kAlpha_8_SkColorType; dstInfo.colorType() must match.
If SkPixmap colorType() is kGray_8_SkColorType, dstInfo.colorSpace() must match.
If SkPixmap alphaType() is kOpaque_SkAlphaType, dstInfo.alphaType() must
match. If SkPixmap colorSpace() is nullptr, dstInfo.colorSpace() must match. Returns
false if pixel conversion is not possible.
Returns false if SkPixmap width() or height() is zero or negative.
@param dstInfo destination width, height, SkColorType, SkAlphaType, SkColorSpace
@param dstPixels destination pixel storage
@param dstRowBytes destination row length
@return true if pixels are copied to dstPixels
*/
bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes) const {
return this->readPixels(dstInfo, dstPixels, dstRowBytes, 0, 0);
}
/** Copies a SkRect of pixels to dstPixels. Copy starts at (srcX, srcY), and does not
exceed SkPixmap (width(), height()).
dstInfo specifies width, height, SkColorType, SkAlphaType, and
SkColorSpace of destination. dstRowBytes specifics the gap from one destination
row to the next. Returns true if pixels are copied. Returns false if
dstInfo address equals nullptr, or dstRowBytes is less than dstInfo.minRowBytes().
Pixels are copied only if pixel conversion is possible. If SkPixmap colorType() is
kGray_8_SkColorType, or kAlpha_8_SkColorType; dstInfo.colorType() must match.
If SkPixmap colorType() is kGray_8_SkColorType, dstInfo.colorSpace() must match.
If SkPixmap alphaType() is kOpaque_SkAlphaType, dstInfo.alphaType() must
match. If SkPixmap colorSpace() is nullptr, dstInfo.colorSpace() must match. Returns
false if pixel conversion is not possible.
srcX and srcY may be negative to copy only top or left of source. Returns
false if SkPixmap width() or height() is zero or negative. Returns false if:
abs(srcX) >= Pixmap width(), or if abs(srcY) >= Pixmap height().
@param dstInfo destination width, height, SkColorType, SkAlphaType, SkColorSpace
@param dstPixels destination pixel storage
@param dstRowBytes destination row length
@param srcX column index whose absolute value is less than width()
@param srcY row index whose absolute value is less than height()
@return true if pixels are copied to dstPixels
*/
bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes, int srcX,
int srcY) const;
/** Copies a SkRect of pixels to dst. Copy starts at (srcX, srcY), and does not
exceed SkPixmap (width(), height()). dst specifies width, height, SkColorType,
SkAlphaType, and SkColorSpace of destination. Returns true if pixels are copied.
Returns false if dst address equals nullptr, or dst.rowBytes() is less than
dst SkImageInfo::minRowBytes.
Pixels are copied only if pixel conversion is possible. If SkPixmap colorType() is
kGray_8_SkColorType, or kAlpha_8_SkColorType; dst.info().colorType must match.
If SkPixmap colorType() is kGray_8_SkColorType, dst.info().colorSpace must match.
If SkPixmap alphaType() is kOpaque_SkAlphaType, dst.info().alphaType must
match. If SkPixmap colorSpace() is nullptr, dst.info().colorSpace must match. Returns
false if pixel conversion is not possible.
srcX and srcY may be negative to copy only top or left of source. Returns
false SkPixmap width() or height() is zero or negative. Returns false if:
abs(srcX) >= Pixmap width(), or if abs(srcY) >= Pixmap height().
@param dst SkImageInfo and pixel address to write to
@param srcX column index whose absolute value is less than width()
@param srcY row index whose absolute value is less than height()
@return true if pixels are copied to dst
*/
bool readPixels(const SkPixmap& dst, int srcX, int srcY) const {
return this->readPixels(dst.info(), dst.writable_addr(), dst.rowBytes(), srcX, srcY);
}
/** Copies pixels inside bounds() to dst. dst specifies width, height, SkColorType,
SkAlphaType, and SkColorSpace of destination. Returns true if pixels are copied.
Returns false if dst address equals nullptr, or dst.rowBytes() is less than
dst SkImageInfo::minRowBytes.
Pixels are copied only if pixel conversion is possible. If SkPixmap colorType() is
kGray_8_SkColorType, or kAlpha_8_SkColorType; dst SkColorType must match.
If SkPixmap colorType() is kGray_8_SkColorType, dst SkColorSpace must match.
If SkPixmap alphaType() is kOpaque_SkAlphaType, dst SkAlphaType must
match. If SkPixmap colorSpace() is nullptr, dst SkColorSpace must match. Returns
false if pixel conversion is not possible.
Returns false if SkPixmap width() or height() is zero or negative.
@param dst SkImageInfo and pixel address to write to
@return true if pixels are copied to dst
*/
bool readPixels(const SkPixmap& dst) const {
return this->readPixels(dst.info(), dst.writable_addr(), dst.rowBytes(), 0, 0);
}
/** Copies SkBitmap to dst, scaling pixels to fit dst.width() and dst.height(), and
converting pixels to match dst.colorType() and dst.alphaType(). Returns true if
pixels are copied. Returns false if dst address is nullptr, or dst.rowBytes() is
less than dst SkImageInfo::minRowBytes.
Pixels are copied only if pixel conversion is possible. If SkPixmap colorType() is
kGray_8_SkColorType, or kAlpha_8_SkColorType; dst SkColorType must match.
If SkPixmap colorType() is kGray_8_SkColorType, dst SkColorSpace must match.
If SkPixmap alphaType() is kOpaque_SkAlphaType, dst SkAlphaType must
match. If SkPixmap colorSpace() is nullptr, dst SkColorSpace must match. Returns
false if pixel conversion is not possible.
Returns false if SkBitmap width() or height() is zero or negative.
Scales the image, with filterQuality, to match dst.width() and dst.height().
filterQuality kNone_SkFilterQuality is fastest, typically implemented with
nearest neighbor filter. kLow_SkFilterQuality is typically implemented with
bilerp filter. kMedium_SkFilterQuality is typically implemented with
bilerp filter, and mip-map filter when size is reduced.
kHigh_SkFilterQuality is slowest, typically implemented with bicubic filter.
@param dst SkImageInfo and pixel address to write to
@param filterQuality one of: kNone_SkFilterQuality, kLow_SkFilterQuality,
kMedium_SkFilterQuality, kHigh_SkFilterQuality
@return true if pixels are scaled to fit dst
*/
bool scalePixels(const SkPixmap& dst, SkFilterQuality filterQuality) const;
/** Writes color to pixels bounded by subset; returns true on success.
Returns false if colorType() is kUnknown_SkColorType, or if subset does
not intersect bounds().
@param color unpremultiplied color to write
@param subset bounding integer SkRect of written pixels
@return true if pixels are changed
*/
bool erase(SkColor color, const SkIRect& subset) const;
/** Writes color to pixels inside bounds(); returns true on success.
Returns false if colorType() is kUnknown_SkColorType, or if bounds()
is empty.
@param color unpremultiplied color to write
@return true if pixels are changed
*/
bool erase(SkColor color) const { return this->erase(color, this->bounds()); }
/** Writes color to pixels bounded by subset; returns true on success.
if subset is nullptr, writes colors pixels inside bounds(). Returns false if
colorType() is kUnknown_SkColorType, if subset is not nullptr and does
not intersect bounds(), or if subset is nullptr and bounds() is empty.
@param color unpremultiplied color to write
@param subset bounding integer SkRect of pixels to write; may be nullptr
@return true if pixels are changed
*/
bool erase(const SkColor4f& color, const SkIRect* subset = nullptr) const;
private:
const void* fPixels;
size_t fRowBytes;
SkImageInfo fInfo;
friend class SkPixmapPriv;
};
#endif

45
skia/include/core/SkPngChunkReader.h vendored Normal file
View File

@ -0,0 +1,45 @@
/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkPngChunkReader_DEFINED
#define SkPngChunkReader_DEFINED
#include "SkTypes.h"
#include "SkRefCnt.h"
/**
* SkPngChunkReader
*
* Base class for optional callbacks to retrieve meta/chunk data out of a PNG
* encoded image as it is being decoded.
* Used by SkCodec.
*/
class SkPngChunkReader : public SkRefCnt {
public:
/**
* This will be called by the decoder when it sees an unknown chunk.
*
* Use by SkCodec:
* Depending on the location of the unknown chunks, this callback may be
* called by
* - the factory (NewFromStream/NewFromData)
* - getPixels
* - startScanlineDecode
* - the first call to getScanlines/skipScanlines
* The callback may be called from a different thread (e.g. if the SkCodec
* is passed to another thread), and it may be called multiple times, if
* the SkCodec is used multiple times.
*
* @param tag Name for this type of chunk.
* @param data Data to be interpreted by the subclass.
* @param length Number of bytes of data in the chunk.
* @return true to continue decoding, or false to indicate an error, which
* will cause the decoder to not return the image.
*/
virtual bool readChunk(const char tag[], const void* data, size_t length) = 0;
};
#endif // SkPngChunkReader_DEFINED

Some files were not shown because too many files have changed in this diff Show More