1.拉取代码
git clone https://skia.googlesource.com/skia
python tools/git-sync-deps
// 这一步可能会出现部分错误,再次执行直到成功
// 这里面拉取完三方库之后会拉取node,linux等压缩包,从google下载
上面执行完,代码就完全拿到了
2.生成ninja
gn gen out/default
// 如果要导出compile_commands.json, 加入--export-compile-commands
// 可以用导出的文件加上clangd和clang配一波智能提示
3.增加自己的demo
skia
├── demo
├── BUILD.gn
└── main.cpp
└── out
增加demo代码如下
#include "include/codec/SkEncodedImageFormat.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkPaint.h"
#include "include/core/SkRect.h"
#include "include/core/SkStream.h"
#include "include/core/SkTextBlob.h"
#include "include/core/SkTypeface.h"
#include "include/encode/SkJpegEncoder.h"
#include "src/core/SkDevice.h"
#include "src/encode/SkImageEncoderFns.h"
const char* pText = "Hello world!";
int main() {
SkBitmap bitmap;
SkImageInfo ii = SkImageInfo::Make(480, 320, kBGRA_8888_SkColorType, kPremul_SkAlphaType);
bitmap.allocPixels(ii, ii.minRowBytes());
SkPaint paint;
paint.setStyle(SkPaint::kStroke_Style);
paint.setColor(0xff1f78b4);
paint.setStrokeWidth(8);
bitmap.allocPixels();
SkCanvas canvas(bitmap);
canvas.clear(0xFF000000); // 背景为透明色
{
SkRect rc;
rc.fLeft = 123;
rc.fTop = 0;
rc.fRight = 222;
rc.fBottom = 50;
canvas.drawOval(rc, paint);
}
{
paint.setColor(SK_ColorYELLOW);
canvas.drawCircle(100, 100, 50, paint);
}
SkFILEWStream stream("./1bc.jpg");
SkJpegEncoder::Encode(&stream, bitmap.pixmap(), {});
return 0;
}
接下来增加同级目录下的BUILD.gn
import("//gn/skia.gni")
skia_executable("demo") {
sources = [
"main.cpp"
]
deps = [
"../.:skia"
]
}
目前还识别不到新增的demo编译目标,需要在总工程目录中增加如下内容
group("gdemo") {
deps = [
"//demo:demo"
]
}
再生成一遍ninja,或者先弄第三步再执行第二步
5.执行编译
ninja -C out/demo demo
待执行编译之后,out/demo中会得到名字为demo的可执行文件,执行,得到生成的jpeg图片,这样我们就能愉快的学习源码了
我绘制文字貌似有问题,之后再写
6.文字绘制(追加)
void draw(SkCanvas* ) {
SkBitmap bitmap;
// create a bitmap 5 wide and 11 high
bitmap.allocPixels(SkImageInfo::MakeN32Premul(5, 11));
SkCanvas canvas(bitmap);
canvas.clear(SK_ColorWHITE); // white is Unpremultiplied, in ARGB order
SkPixmap pixmap; // provides guaranteed access to the drawn pixels
if (!canvas.peekPixels(&pixmap)) {
SkDebugf("peekPixels should never fail.\n");
}
const SkPMColor* pixels = pixmap.addr32(); // points to top-left of bitmap
SkPMColor pmWhite = pixels[0]; // the Premultiplied format may vary
SkPaint paint; // by default, draws black, 12 point text
SkFont font = SkFont(fontMgr->matchFamilyStyle(nullptr, {}));
canvas.drawString("!", 1, 10, font, paint); // 1 char at baseline (1, 10)
for (int y = 0; y < bitmap.height(); ++y) {
for (int x = 0; x < bitmap.width(); ++x) {
SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
}
SkDebugf("\n");
}
}
这段代码是源码中的示例,在官网提供的链接中运行当前代码,发现可以打印感叹号
-----
--xx-
--xx-
--xx-
--xx-
--xx-
--xx-
-----
--xx-
--xx-
-----
代码拿来进demo中发现缺少fontMgr
变量定义,搜索源码fontMgr发现如下源码
易得网页上面的代码应该是编译的这里的源码,通过头文件中的宏定义注册测试代码到列表中运行,那么我们只要能自己获取fontMgr
显示出来,那么源代码的demo就应该能显示出来。第一个就好使,然后打印个hello world吧,典
代码如下
#include "include/core/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkPaint.h"
#include "include/core/SkTextBlob.h"
#include "include/core/SkTypeface.h"
#include "include/ports/SkFontMgr_fontconfig.h"
#include "include/ports/SkFontScanner_FreeType.h"
#include "include/core/SkFontMgr.h"
int main() {
SkBitmap bitmap;
// create a bitmap 100 wide and 20 high
bitmap.allocPixels(SkImageInfo::MakeN32Premul(100, 20));
SkCanvas canvas(bitmap);
canvas.clear(SK_ColorWHITE);
SkPixmap pixmap;
if (!canvas.peekPixels(&pixmap)) {
SkDebugf("peekPixels should never fail.\n");
}
const SkPMColor* pixels = pixmap.addr32();
SkPMColor pmWhite = pixels[0];
SkPaint paint; // by default, draws black, 12 point text
sk_sp<SkFontMgr> fontMgr1 = SkFontMgr_New_FontConfig(nullptr, SkFontScanner_Make_FreeType());
SkFont font = SkFont(fontMgr1->matchFamilyStyle(nullptr, {}));
canvas.drawString("hello world", 1, 10, font, paint); // 1 char at baseline (1, 10)
for (int y = 0; y < bitmap.height(); ++y) {
for (int x = 0; x < bitmap.width(); ++x) {
SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x');
}
SkDebugf("\n");
}
return 0;
}
7.编译库(追加)
通过上面的编译可以发现生成的可执行文件特别大,竟然有一百多兆。
查找toolchain发现,编译skia
库的默认工具链如下
template("component") {
_component_mode = "static_library"
if (is_component_build) {
_component_mode = "shared_library"
}
target(_component_mode, target_name) {
forward_variables_from(invoker, "*")
}
}
搜索is_component_build发现,原来是false,直接编译静态库了,怪不得这么大
那么新增参数编译动态库
gn gen out/demo --args="is_component_build=true"
或者直接在out/demo/args.gn
中增加
8.尚待解决(追加)
编译动态库加上字体不会生成字体的动态库,不加字体可以。当然,静态库没毛病。