Android 深色模式适配原理分析( 五 )
frameworks/base/libs/hwui/RecordingCanvas.cpp
void DisplayListData::applyColorTransform(ColorTransform transform) {// 使用transform作为参数执行color_transform_fns函数组this->map(color_transform_fns, transform);}template inline void DisplayListData::map(const Fn fns[], Args... args) const {auto end = fBytes.get() + fUsed;// 遍历需要绘制的元素op , 并调用对应类型的colorTransformForOp函数for (const uint8_t* ptr = fBytes.get(); ptr < end;) {auto op = (const Op*)ptr;auto type = op->type;auto skip = op->skip;if (auto fn = fns[type]) {// We replace no-op functions with nullptrsfn(op, args...);// to avoid the overhead of a pointless call.}ptr += skip;}}typedef void (*color_transform_fn)(const void*, ColorTransform);#define X(T) colorTransformForOp(),static const color_transform_fn color_transform_fns[] = {// 相当于 colorTransformForOp
frameworks/base/libs/hwui/CanvasTransform.cpp
这里进行具体的颜色转换逻辑 , 我们首先关注非Bitmap绘制的颜色转换
// 非Bitmap绘制颜色模式转换bool transformPaint(ColorTransform transform, SkPaint* paint) {applyColorTransform(transform, *paint);return true;}// 非Bitmap绘制颜色模式转换static void applyColorTransform(ColorTransform transform, SkPaint// 具体绘制颜色转换逻辑SkColor newColor = transformColor(transform, paint.getColor());// 将画笔颜色修改为转换后的颜色paint.setColor(newColor);// 有渐变色情况if (paint.getShader()) {SkShader::GradientInfo info;std::array _colorStorage;std::array _offsetStorage;info.fColorCount = _colorStorage.size();info.fColors = _colorStorage.data();info.fColorOffsets = _offsetStorage.data();SkShader::GradientType type = paint.getShader()->asAGradient(if (info.fColorCount <= 10) {switch (type) {// 线性渐变并且渐变颜色少于等于10个的情况case SkShader::kLinear_GradientType:for (int i = 0; i < info.fColorCount; i++) {// 对渐变色颜色进行转换info.fColors[i] = transformColor(transform, info.fColors[i]);}paint.setShader(SkGradientShader::MakeLinear(info.fPoint, info.fColors,info.fColorOffsets, info.fColorCount,info.fTileMode, info.fGradientFlags, nullptr));break;default:break;}}}// 处理colorFilterif (paint.getColorFilter()) {SkBlendMode mode;SkColor color;// TODO: LRU this or something to avoid spamming new color mode filtersif (paint.getColorFilter()->asAColorMode(paint.setColorFilter(SkColorFilters::Blend(color, mode));}}}static SkColor transformColor(ColorTransform transform, SkColor color) {switch (transform) {case ColorTransform::Light:return makeLight(color);case ColorTransform::Dark:return makeDark(color);default:return color;}}// 前景色变亮static SkColor makeLight(SkColor color) {// 将sRGB色彩模式转换成Lab色彩模式Lab lab = sRGBToLab(color);// 对亮度L维度取反float invertedL = std::min(110 - lab.L, 100.0f);if (invertedL > lab.L) {// 若取反后亮度变亮 , 则替换原来亮度lab.L = invertedL;// 重新转换为sRGB模式return LabToSRGB(lab, SkColorGetA(color));} else {return color;}}// 后景色变暗static SkColor makeDark(SkColor color) {// 将sRGB色彩模式转换成Lab色彩模式Lab lab = sRGBToLab(color);// 对亮度L维度取反float invertedL = std::min(110 - lab.L, 100.0f);if (invertedL
- 运动计数开发项目的对抗赛:飞算全自动软件工程平台碾压传统模式
- 莆田:科技与创意引领制鞋新模式
- 华为开启“暴走”模式!三个大动作同时展开,国产芯片将迎来破冰
- 联想发布新款11英寸Android平板电脑Tab P11
- 送餐机器人等创新模式助力餐饮行业复苏发展
- 向日葵Android客户端5.0更新:新增两种免root远控方式
- 一加披露Android 11升级计划 OnePlus 6与Nord 10系列皆有份
- 青少年|封面评论 |“青少年模式”依旧漏洞百出,标准化合规框架必须落地
- 聊聊网易云音乐:“心动模式”
- Windows 10端Chromium改善防病毒软件兼容性和深色模式