mirror of https://github.com/Chlumsky/msdfgen.git
Skia integration - preprocessing of shape geometry
This commit is contained in:
parent
fe910c8b5a
commit
9d22335ea0
|
|
@ -2,3 +2,4 @@
|
|||
include/** linguist-vendored
|
||||
lib/** linguist-vendored
|
||||
freetype/** linguist-vendored
|
||||
skia/** linguist-vendored
|
||||
|
|
|
|||
|
|
@ -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/
|
||||
|
|
|
|||
19
CHANGELOG.md
19
CHANGELOG.md
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Binary file not shown.
BIN
Msdfgen.rc
BIN
Msdfgen.rc
Binary file not shown.
|
|
@ -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" />
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
74
main.cpp
74
main.cpp
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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
|
||||
|
|
@ -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
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
Loading…
Reference in New Issue