From 4783122435299e21338e217552f2829a38b981a6 Mon Sep 17 00:00:00 2001 From: sloop Date: Mon, 18 Jul 2016 02:12:12 +0800 Subject: [PATCH 01/61] =?UTF-8?q?=E9=AD=94=E6=B3=95-=E6=B7=B7=E6=B2=8C?= =?UTF-8?q?=E4=BC=8A=E5=A7=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ChaosCrystal/HowToViewAPISourceOnline.md | 12 - ChaosCrystal/README.md | 9 - Course/HowToUsePlantUMLInAS.md | 55 -- Course/README.md | 6 - Course/ReleaseLibraryByJitPack.md | 160 ----- CustomView/Advance/Code/SearchView.md | 249 -------- CustomView/Advance/Res/Checkmark.png | Bin 9067 -> 0 bytes CustomView/Advance/[1]CustomViewProcess.md | 245 -------- CustomView/Advance/[2]Canvas_BasicGraphics.md | 541 ---------------- CustomView/Advance/[3]Canvas_Convert.md | 448 ------------- CustomView/Advance/[4]Canvas_PictureText.md | 506 --------------- CustomView/Advance/[5]Path_Basic.md | 581 ----------------- CustomView/Advance/[6]Path_Bezier.md | 591 ------------------ CustomView/Advance/[7]Path_Over.md | 412 ------------ CustomView/Advance/[8]Path_Play.md | 552 ---------------- CustomView/Advance/[99]DrawText.md | 279 --------- CustomView/Advance/[9]Matrix_Basic.md | 48 -- CustomView/Base/[1]CoordinateSystem.md | 67 -- CustomView/Base/[2]AngleAndRadian.md | 74 --- CustomView/Base/[3]Color.md | 159 ----- CustomView/README.md | 39 -- GankDevelopmentNote/chapter_1.md | 65 -- LICENSE | 202 ------ QuickChart/Bezier.md | 12 - QuickChart/Canvas.md | 14 - QuickChart/Matrix.md | 1 - QuickChart/Path.md | 31 - QuickChart/README.md | 7 - README.md | 51 +- 29 files changed, 2 insertions(+), 5414 deletions(-) delete mode 100644 ChaosCrystal/HowToViewAPISourceOnline.md delete mode 100644 ChaosCrystal/README.md delete mode 100644 Course/HowToUsePlantUMLInAS.md delete mode 100644 Course/README.md delete mode 100644 Course/ReleaseLibraryByJitPack.md delete mode 100644 CustomView/Advance/Code/SearchView.md delete mode 100755 CustomView/Advance/Res/Checkmark.png delete mode 100644 CustomView/Advance/[1]CustomViewProcess.md delete mode 100644 CustomView/Advance/[2]Canvas_BasicGraphics.md delete mode 100644 CustomView/Advance/[3]Canvas_Convert.md delete mode 100644 CustomView/Advance/[4]Canvas_PictureText.md delete mode 100644 CustomView/Advance/[5]Path_Basic.md delete mode 100644 CustomView/Advance/[6]Path_Bezier.md delete mode 100644 CustomView/Advance/[7]Path_Over.md delete mode 100644 CustomView/Advance/[8]Path_Play.md delete mode 100644 CustomView/Advance/[99]DrawText.md delete mode 100644 CustomView/Advance/[9]Matrix_Basic.md delete mode 100644 CustomView/Base/[1]CoordinateSystem.md delete mode 100644 CustomView/Base/[2]AngleAndRadian.md delete mode 100644 CustomView/Base/[3]Color.md delete mode 100644 CustomView/README.md delete mode 100644 GankDevelopmentNote/chapter_1.md delete mode 100644 LICENSE delete mode 100644 QuickChart/Bezier.md delete mode 100644 QuickChart/Canvas.md delete mode 100644 QuickChart/Matrix.md delete mode 100644 QuickChart/Path.md delete mode 100644 QuickChart/README.md diff --git a/ChaosCrystal/HowToViewAPISourceOnline.md b/ChaosCrystal/HowToViewAPISourceOnline.md deleted file mode 100644 index b0e07bc7..00000000 --- a/ChaosCrystal/HowToViewAPISourceOnline.md +++ /dev/null @@ -1,12 +0,0 @@ -# 在线查看Android API源码的方法 - - -方法 | 推荐程度| 链接 | 备注 ----|---|---|--- -官方GitHub仓库 | ★☆☆☆☆ | [GitHub-Android](https://github.com/android) | 搜索不方便 -通过GrepCode | ★★★☆☆ | [GrepCode-Android](http://grepcode.com/project/repository.grepcode.com/java/ext/com.google.android/android/) | 有搜索功能,可以在线查看到各个版本的源码,也可以下载 -通过Chrome插件 | ★★★★★ | [插件:SDKSearch](https://chrome.google.com/webstore/detail/android-sdk-search/hgcbffeicehlpmgmnhnkjbjoldkfhoin)
[Android API官网](http://developer.android.com/reference/packages.html) | 在官网查看API时会在下面多出一个View Source按钮(如下图) - -![](http://ww3.sinaimg.cn/large/005Xtdi2jw1f3tvw0e7exj30du07tq32.jpg) - - diff --git a/ChaosCrystal/README.md b/ChaosCrystal/README.md deleted file mode 100644 index 2514ba44..00000000 --- a/ChaosCrystal/README.md +++ /dev/null @@ -1,9 +0,0 @@ -![](http://ww1.sinaimg.cn/large/005Xtdi2jw1f5xd2k7s8hj30x30d8tab.jpg) - -# 混沌水晶 - -混沌水晶本身并没有太大功效,但与其他物品合成之后可能产生质的变化。 - -序号 | 内容 -:---:|--------------- - 01 | [在线查看Android API源码](https://github.com/GcsSloop/AndroidNote/blob/master/ChaosCrystal/HowToViewAPISourceOnline.md) diff --git a/Course/HowToUsePlantUMLInAS.md b/Course/HowToUsePlantUMLInAS.md deleted file mode 100644 index ea1ef7de..00000000 --- a/Course/HowToUsePlantUMLInAS.md +++ /dev/null @@ -1,55 +0,0 @@ -# 在AndroidStudio中使用PlantUML - -### 作者微博: [@GcsSloop](http://weibo.com/GcsSloop) - -## 前言 - -**Unified Modeling Language (UML)又称统一建模语言或标准建模语言,用来描述 类(对象的)、对象、关联、职责、行为、接口、用例、包、顺序、协作,以及状态。是用来帮助自己理清众多类之间复杂关系的不二利器,也能帮助别人快速理解你的设计思路。** - -那么,我们怎么在AndroidStudio中创建自己的UML类图呢?接下来我就教大家如何用正确的姿势创建UML类图。 - -## 一.用正确的姿势安装panltUML插件 -### 1.File->Settings->Plugins->Browse repositories -![这里写图片描述](http://img.blog.csdn.net/20151130192101011) -### 2.在搜索框输入plantUML -![这里写图片描述](http://img.blog.csdn.net/20151130192547549) -### 3.导入插件 -#### (ps:由于我已经安装过了,所以没有Install plugin 按钮,未安装的都有这样一个按钮,如下,点击安装即可。) -![这里写图片描述](http://img.blog.csdn.net/20151130192907006) - -#### 如果以上步骤正确的完成,重启AndroidStudio 右键->new 的时候你会发现多了这么一堆东西,如果出现了这些说明plantUML已经正确的安装了。 -![这里写图片描述](http://img.blog.csdn.net/20151130193249965) - -#### 当然了,所有事情都不会是一帆风顺的,当你迫不及待的想创建一个文件试试的时候你会发现下面的情况。 -![这里写图片描述](http://img.blog.csdn.net/20151130193752721) -#### 想必此时你的内心一定和我当时一样,一万头草泥马奔腾而过,这都是什么东西!!! -#### 一切事情都是有原因的,而这个因为你还缺少一个必要的东西,就是大名鼎鼎的贝尔实验室开发的一个工具包:Graphviz。 -## 二,用正确的姿势安装Graphviz -### 1.下载Graphviz -###[【下载地址戳这里】](http://www.graphviz.org/Download_windows.php) -![这里写图片描述](http://img.blog.csdn.net/20151130194703804) -### 2.安装 -#### 安装过程我就不详细讲解了,点击next后要记住安装的目录。之后下一步,直到完成就行。 -![这里写图片描述](http://img.blog.csdn.net/20151130195454083) - -## 三.用正确的姿势设置plantUML -### 1.点击右上角的设置按钮或进入File->Settings->Other Settings ->PlantUML -### 2.将文件路径填写为刚刚Graphviz的目录下bin目录中dot.exe文件。 -#### (我的为:D:/Program/Graphviz/bin/dot.exe) -![这里写图片描述](http://img.blog.csdn.net/20151130200308586) -### 3.点击OK 刷新一下界面就能看到这个了。 -![这里写图片描述](http://img.blog.csdn.net/20151130200452927) -#### 讲到这里,就已经安装完成了,可以愉快的用代码来书写UML图了。 -#### 什么?你说你还不会书写的语法?没关系,其实我也不会,不过我有一个好的教程推荐给你,相信你看完就明白啦。 -## 四.用正确的姿势学习使用UML -### 1.[【PlantUML快速指南戳这里】](http://archive.3zso.com/archives/plantuml-quickstart.html) -### 2.注意,这个教程中的语法和AndroidStudio中基本一致,区别就是开始和结束标志不同。 - -####好了,到这里该教程正式结束,祝各位小伙伴能愉快的使用plantUML玩耍。 - -## About Me -### 作者微博: [@GcsSloop](http://weibo.com/GcsSloop) - - - - diff --git a/Course/README.md b/Course/README.md deleted file mode 100644 index 67b44aba..00000000 --- a/Course/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# 教程类 - -**教程类** | -:---: | - | - | diff --git a/Course/ReleaseLibraryByJitPack.md b/Course/ReleaseLibraryByJitPack.md deleted file mode 100644 index 18b3dbf6..00000000 --- a/Course/ReleaseLibraryByJitPack.md +++ /dev/null @@ -1,160 +0,0 @@ -# 优雅的发布Android开源库(论JitPack的优越性) -### 作者微博: @GcsSloop -### [JitPack地址](https://jitpack.io) - -## 前言 -自从谷歌宣布不支持Eclipse之后,大批Android程序猿情愿或者不情愿的迁移到了AndroidStudio,从此过上了使用Gradle构建程序的"优越"生活。 - -> 关于Gradle的坑,就不吐槽了,我怕一会儿控制不住情绪。今天我们就谈一下Gradle的优越性。 - -说到Gradle的优越性,其中有一点比较明显的就是依赖开源库更加方便了,基本上一两行代码就能搞定。免去了还要手动下载自己配置的痛苦。 - -然而,这也仅仅是对使用者而言,而对于发布这些开源库的人就苦逼了,主要是上传太痛苦。 - -目前来说,比较常见的 Android 开源库托管地址有以下几类: - -类型 | 吐槽 -------------- | ------------ -Maven Central | 发布过程繁杂冗长, 每次发布成功都应该感谢一下上苍的厚爱。 -jCenter | jCenter貌似稍微简单一点,但也不是省油的灯。 -自定义仓库 | 一般的猿猿玩不起,企业内部可能会见到。 - -在这些托管地址上面发布过项目的都应该能理解其中的痛苦,不说了,让我哭会儿(我就是那个每次发布都折腾半天的“bug狂魔”,从未一次发布就成功过)。 - -然而,现在福音来了,JitPack可以帮助你简单快速的发布开源库。 - -## 在正式讲解之前我们先了解一下JitPack - -**JitPack是什么?** - -> **JitPack是一个自定义的Maven仓库。** - -**JitPack安全吗?** - -> **个人还是比较安全的,毕竟开源库都是给大家用的,源码都能分享出来,如果你是担心它在里面插入恶意代码的话,在AndroidStudio的 External Libraies里面能够看到反编译的依赖库的源码,可以查看一下。** - -**JitPack好处都有啥!说对我就给他用(金坷垃,雾)** - -> **省时间,省时间,省时间,省下的时间都够你修复好几个bug了。** - -简单的了解了JitPack之后,开始本篇的正文。 - - -# 如何在JitPack上发布你的Library - -**首先,假设大家已经具备了以下条件:** - -序号 | 条件 -:---:|--------- - 1 | 会使用GitHub,能提交项目到GitHub上 - 2 | 使用AndroidStudio,且Gradle版本在2.4以上 - -在具备了这些条件之后,正式开始发布一个项目(以我的一个[工具仓库Sutil](https://github.com/GcsSloop/SUtil)为例)。 - -## 第 1 步: 新建一个Project - -在AndroidStudio中新建一个Project用于发布项目,新建完成之后结果是这样子: - -![](http://ww1.sinaimg.cn/large/005Xtdi2jw1f239wl5amtj30rs0gon0g.jpg) - -## 第 2 步: 在这个Project中添加一个Library - -添加的这个Library就是我要发布的仓库,Library的名字无所谓,可以随便起(*我这里就叫library*)。添加完成之后是这样子: - -![](http://ww2.sinaimg.cn/large/005Xtdi2jw1f239xb835xj30rs0gowiv.jpg) - -### 图中的几个标注 - -序号 | 解释 -:---:|------- - 1 | 新添加的Library - 2 | Library的build.gradle - 3 | Library的plugin - -**其中library的plugin是下面这样子:** - -``` gradle -apply plugin: 'com.android.library' -``` - -## 第 3 步: 给你的项目添加配置(重点) - -你需要对你的项目简单的配置一下: - -![](http://ww4.sinaimg.cn/large/005Xtdi2jw1f239y5xsj4j30rs0gowit.jpg) - -**在你项目的根节点的 build.gradle(图示1) 中添加如下代码:** - -``` gradle -buildscript { - dependencies { - // 重点就是下面这一行(上面两行是为了定位这一行的添加位置) - classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3' -``` -**[完整示例](https://github.com/GcsSloop/SUtil/blob/master/build.gradle)** - -**在你要发布的library的 build.gradle(图示2) 中添加如下代码:** - -``` gradle - apply plugin: 'com.github.dcendents.android-maven' - - group='com.github.YourUsername' -``` -**[完整示例](https://github.com/GcsSloop/SUtil/blob/master/library/build.gradle)** - -## 第 4 步: 提交项目到GitHub仓库 - -这一步就不多啰嗦了,不论你是用命令行还是客户端都可以。 - -**为了提交更加快速,你可以删除无用的文件(文件夹),至于需要保留哪些文件你可以参考官方给出的[示例仓库](https://github.com/jitpack/android-example)** - -## 第 5 步: Release你的仓库或者给你的仓库打一个Tag(重点) - -### 1.点击图示进入Release界面 -![](http://ww3.sinaimg.cn/large/005Xtdi2jw1f239yqr44cj30rs0goadk.jpg) - -### 2.创建一个Release或Tag -![](http://ww3.sinaimg.cn/large/005Xtdi2jw1f239z1dnr8j30rs0goaco.jpg) - -### 3.填写基本信息 -![](http://ww4.sinaimg.cn/large/005Xtdi2jw1f239zctc5xj30rs0goq7w.jpg) - -### 4.完成 -![](http://ww1.sinaimg.cn/large/005Xtdi2jw1f239zpfkcwj30rs0gogns.jpg) - -## 第 6 步: 将你的仓库地址提交到JitPack(重点) - -### 1.将你的仓库地址提交到[JitPack](https://jitpack.io) -**[JitPack地址戳这里](https://jitpack.io)** - -![](http://ww3.sinaimg.cn/large/005Xtdi2jw1f23a055uoej30rs0godi0.jpg) - -序号 | 解释 -:---:|-------- - 1 | 粘贴你的仓库地址 - 2 | 点击这里查看 - 3 | 版本号 - 4 | 点击这里提交该版本 - 5 | 提交完成后自动生成的日志 - -### 2.JitPack自动生成的配置信息 -在上传完成之后,JitPack会自动生成引用该仓库的配置信息,如下: - -![](http://ww4.sinaimg.cn/large/005Xtdi2jw1f23a0fd5iyj30rs0gotb2.jpg) - -**以上就是教程的全部内容,各位小伙伴可以回去愉快的发布自己的开源库了。** -### [JitPack地址](https://jitpack.io) - -## About Me - -### 作者微博: @GcsSloop - - - - - - - - - - diff --git a/CustomView/Advance/Code/SearchView.md b/CustomView/Advance/Code/SearchView.md deleted file mode 100644 index 13af1f7c..00000000 --- a/CustomView/Advance/Code/SearchView.md +++ /dev/null @@ -1,249 +0,0 @@ -## SearchView 源代码 - -``` java -/** - * Author: GcsSloop - *

- * Created Date: 16/5/31 - *

- * Copyright (C) 2016 GcsSloop. - *

- * GitHub: https://github.com/GcsSloop - */ -public class SearchView extends View { - - // 画笔 - private Paint mPaint; - - // View 宽高 - private int mViewWidth; - private int mViewHeight; - - // 这个视图拥有的状态 - public static enum State { - NONE, - STARTING, - SEARCHING, - ENDING - } - - // 当前的状态(非常重要) - private State mCurrentState = State.NONE; - - // 放大镜与外部圆环 - private Path path_srarch; - private Path path_circle; - - // 测量Path 并截取部分的工具 - private PathMeasure mMeasure; - - // 默认的动效周期 2s - private int defaultDuration = 2000; - - // 控制各个过程的动画 - private ValueAnimator mStartingAnimator; - private ValueAnimator mSearchingAnimator; - private ValueAnimator mEndingAnimator; - - // 动画数值(用于控制动画状态,因为同一时间内只允许有一种状态出现,具体数值处理取决于当前状态) - private float mAnimatorValue = 0; - - // 动效过程监听器 - private ValueAnimator.AnimatorUpdateListener mUpdateListener; - private Animator.AnimatorListener mAnimatorListener; - - // 用于控制动画状态转换 - private Handler mAnimatorHandler; - - // 判断是否已经搜索结束 - private boolean isOver = false; - - private int count = 0; - - public SearchView(Context context) { - super(context); - - initPaint(); - - initPath(); - - initListener(); - - initHandler(); - - initAnimator(); - - // 进入开始动画 - mCurrentState = State.STARTING; - mStartingAnimator.start(); - - } - - private void initPaint() { - mPaint = new Paint(); - mPaint.setStyle(Paint.Style.STROKE); - mPaint.setColor(Color.WHITE); - mPaint.setStrokeWidth(15); - mPaint.setStrokeCap(Paint.Cap.ROUND); - mPaint.setAntiAlias(true); - } - - private void initPath() { - path_srarch = new Path(); - path_circle = new Path(); - - mMeasure = new PathMeasure(); - - // 注意,不要到360度,否则内部会自动优化,测量不能取到需要的数值 - RectF oval1 = new RectF(-50, -50, 50, 50); // 放大镜圆环 - path_srarch.addArc(oval1, 45, 359.9f); - - RectF oval2 = new RectF(-100, -100, 100, 100); // 外部圆环 - path_circle.addArc(oval2, 45, -359.9f); - - float[] pos = new float[2]; - - mMeasure.setPath(path_circle, false); // 放大镜把手的位置 - mMeasure.getPosTan(0, pos, null); - - path_srarch.lineTo(pos[0], pos[1]); // 放大镜把手 - - Log.i("TAG", "pos=" + pos[0] + ":" + pos[1]); - } - - private void initListener() { - mUpdateListener = new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - mAnimatorValue = (float) animation.getAnimatedValue(); - invalidate(); - } - }; - - mAnimatorListener = new Animator.AnimatorListener() { - @Override - public void onAnimationStart(Animator animation) { - - } - - @Override - public void onAnimationEnd(Animator animation) { - // getHandle发消息通知动画状态更新 - mAnimatorHandler.sendEmptyMessage(0); - } - - @Override - public void onAnimationCancel(Animator animation) { - - } - - @Override - public void onAnimationRepeat(Animator animation) { - - } - }; - } - - private void initHandler() { - mAnimatorHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - super.handleMessage(msg); - switch (mCurrentState) { - case STARTING: - // 从开始动画转换好搜索动画 - isOver = false; - mCurrentState = State.SEARCHING; - mStartingAnimator.removeAllListeners(); - mSearchingAnimator.start(); - break; - case SEARCHING: - if (!isOver) { // 如果搜索未结束 则继续执行搜索动画 - mSearchingAnimator.start(); - Log.e("Update", "RESTART"); - - count++; - if (count>2){ // count大于2则进入结束状态 - isOver = true; - } - } else { // 如果搜索已经结束 则进入结束动画 - mCurrentState = State.ENDING; - mEndingAnimator.start(); - } - break; - case ENDING: - // 从结束动画转变为无状态 - mCurrentState = State.NONE; - break; - } - } - }; - } - - private void initAnimator() { - mStartingAnimator = ValueAnimator.ofFloat(0, 1).setDuration(defaultDuration); - mSearchingAnimator = ValueAnimator.ofFloat(0, 1).setDuration(defaultDuration); - mEndingAnimator = ValueAnimator.ofFloat(1, 0).setDuration(defaultDuration); - - mStartingAnimator.addUpdateListener(mUpdateListener); - mSearchingAnimator.addUpdateListener(mUpdateListener); - mEndingAnimator.addUpdateListener(mUpdateListener); - - mStartingAnimator.addListener(mAnimatorListener); - mSearchingAnimator.addListener(mAnimatorListener); - mEndingAnimator.addListener(mAnimatorListener); - } - - - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - super.onSizeChanged(w, h, oldw, oldh); - mViewWidth = w; - mViewHeight = h; - } - - @Override - protected void onDraw(Canvas canvas) { - super.onDraw(canvas); - - drawSearch(canvas); - } - - private void drawSearch(Canvas canvas) { - - mPaint.setColor(Color.WHITE); - - - canvas.translate(mViewWidth / 2, mViewHeight / 2); - - canvas.drawColor(Color.parseColor("#0082D7")); - - switch (mCurrentState) { - case NONE: - canvas.drawPath(path_srarch, mPaint); - break; - case STARTING: - mMeasure.setPath(path_srarch, false); - Path dst = new Path(); - mMeasure.getSegment(mMeasure.getLength() * mAnimatorValue, mMeasure.getLength(), dst, true); - canvas.drawPath(dst, mPaint); - break; - case SEARCHING: - mMeasure.setPath(path_circle, false); - Path dst2 = new Path(); - float stop = mMeasure.getLength() * mAnimatorValue; - float start = (float) (stop - ((0.5 - Math.abs(mAnimatorValue - 0.5)) * 200f)); - mMeasure.getSegment(start, stop, dst2, true); - canvas.drawPath(dst2, mPaint); - break; - case ENDING: - mMeasure.setPath(path_srarch, false); - Path dst3 = new Path(); - mMeasure.getSegment(mMeasure.getLength() * mAnimatorValue, mMeasure.getLength(), dst3, true); - canvas.drawPath(dst3, mPaint); - break; - } - } -} - -``` diff --git a/CustomView/Advance/Res/Checkmark.png b/CustomView/Advance/Res/Checkmark.png deleted file mode 100755 index b8b881ce540cf69c06d88a9072210a5992078895..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9067 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 QF$lYgx{fSTzZLwy0He!$YybcN diff --git a/CustomView/Advance/[1]CustomViewProcess.md b/CustomView/Advance/[1]CustomViewProcess.md deleted file mode 100644 index dcbbc99b..00000000 --- a/CustomView/Advance/[1]CustomViewProcess.md +++ /dev/null @@ -1,245 +0,0 @@ -# 自定义View分类与流程 - -### 作者微博: [@GcsSloop](http://weibo.com/GcsSloop) -### [【本系列相关文章】](https://github.com/GcsSloop/AndroidNote/tree/master/CustomView) - -经历过前面三篇啰啰嗦嗦的基础篇之后,终于到了进阶篇,正式进入解析自定义View的阶段。 - -## 前言 -**本章节为什么要叫进阶篇?(虽然讲的是基础内容),因为从本篇开始,将会逐渐揭开自定义View的神秘面纱,每一篇都将比上一篇内容更加深入,利用所学的知识能够制作更加炫酷自定义View,就像在台阶上一样,每一篇都更上一层,~~帮助大家一步步走向人生巅峰,出任CEO,迎娶白富美。~~ 误,是帮助大家更加了解那些炫酷的自定义View是如何制作的,达到举一反三的效果。** - - -## 一.自定义View分类 - -**我将自定义View分为了两类(sloop个人分类法,非官方):** - -### 1.自定义ViewGroup - - **自定义ViewGroup一般是利用现有的组件根据特定的布局方式来组成新的组件,大多继承自ViewGroup或各种Layout,包含有子View。** - -> 例如:应用底部导航条中的条目,一般都是上面图标(ImageView),下面文字(TextView),那么这两个就可以用自定义ViewGroup组合成为一个Veiw,提供两个属性分别用来设置文字和图片,使用起来会更加方便。 - -### 2.自定义View - - **在没有现成的View,需要自己实现的时候,就使用自定义View,一般继承自View,SurfaceView或其他的View,不包含子View。** - -> 例如:制作一个支持自动加载网络图片的ImageView,制作图表等。 - -**PS: 自定义View在大多数情况下都有替代方案,利用图片或者组合动画来实现,但是使用后者可能会面临内存耗费过大,制作麻烦更诸多问题。** - -******* - -## 二.几个重要的函数 - -### 1.构造函数 - -构造函数是View的入口,可以用于**初始化一些的内容,和获取自定义属性**。 - -View的构造函数有四种重载分别如下: -``` java - public void SloopView(Context context) {} - public void SloopView(Context context, AttributeSet attrs) {} - public void SloopView(Context context, AttributeSet attrs, int defStyleAttr) {} - public void SloopView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {} -``` - 可以看出,关于View构造函数的参数有多有少,先排除几个不常用的,留下常用的再研究。 - - **有四个参数的构造函数在API21的时候才添加上,暂不考虑。** - -有三个参数的构造函数中第三个参数是默认的Style,这里的默认的Style是指它在当前Application或Activity所用的Theme中的默认Style,且只有在明确调用的时候才会生效,以系统中的ImageButton为例说明: -``` java - public ImageButton(Context context, AttributeSet attrs) { - //调用了三个参数的构造函数,明确指定第三个参数 - this(context, attrs, com.android.internal.R.attr.imageButtonStyle); - } - - public ImageButton(Context context, AttributeSet attrs, int defStyleAttr) { - //此处调了四个参数的构造函数,无视即可 - this(context, attrs, defStyleAttr, 0); - } -``` -**注意:即使你在View中使用了Style这个属性也不会调用三个参数的构造函数,所调用的依旧是两个参数的构造函数。** - -**由于三个参数的构造函数第三个参数一般不用,暂不考虑,第三个参数的具体用法会在以后用到的时候详细介绍。** - -排除了两个之后,只剩下一个参数和两个参数的构造函数,他们的详情如下: -``` java - //一般在直接New一个View的时候调用。 - public void SloopView(Context context) {} - - //一般在layout文件中使用的时候会调用,关于它的所有属性(包括自定义属性)都会包含在attrs中传递进来。 - public void SloopView(Context context, AttributeSet attrs) {} -``` -**以下方法调用的是一个参数的构造函数:** -``` java - //在Avtivity中 - SloopView view = new SloopView(this); -``` -**以下方法调用的是两个参数的构造函数:** -``` xml - //在layout文件中 - 格式为: 包名.View名 - -``` -关于构造函数先讲这么多,关于如何自定义属性和使用attrs中的内容,在后面会详细讲解,目前只需要知道这两个构造函数在何时调用即可。 - -======== - -### 2.测量View大小(onMeasure) - -**Q: 为什么要测量View大小?** - -**A: View的大小不仅由自身所决定,同时也会受到父控件的影响,为了我们的控件能更好的适应各种情况,一般会自己进行测量。** - -测量View大小使用的是onMeasure函数,我们可以从onMeasure的两个参数中取出宽高的相关数据: -``` java - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - int widthsize = MeasureSpec.getSize(widthMeasureSpec); //取出宽度的确切数值 - int widthmode = MeasureSpec.getMode(widthMeasureSpec); //取出宽度的测量模式 - - int heightsize = MeasureSpec.getSize(heightMeasureSpec); //取出高度的确切数值 - int heightmode = MeasureSpec.getMode(heightMeasureSpec); //取出高度的测量模式 - } -``` -从上面可以看出 onMeasure 函数中有 widthMeasureSpec 和 heightMeasureSpec 这两个 int 类型的参数, 毫无疑问他们是和宽高相关的, **但它们其实不是宽和高, 而是由宽、高和各自方向上对应的测量模式来合成的一个值:** - -**测量模式一共有三种, 被定义在 Android 中的 View 类的一个内部类View.MeasureSpec中:** - -模式 | 二进制数值 | 描述 ------------ |:----------:| --- -UNSPECIFIED | 00 | 默认值,父控件没有给子view任何限制,子View可以设置为任意大小。 -EXACTLY | 01 | 表示父控件已经确切的指定了子View的大小。 -AT_MOST | 10 | 表示子View具体大小没有尺寸限制,但是存在上限,上限一般为父View大小。 - -**在int类型的32位二进制位中,31-30这两位表示测量模式,29~0这三十位表示宽和高的实际值,实际上如下:** - -以数值1080(二进制为: 1111011000)为例(其中模式和实际数值是连在一起的,为了展示我将他们分开了): - -模式名称 | 模式数值 | 实际数值 -------------| --------:| --- -UNSPECIFIED | 00 | 000000000000000000001111011000 -EXACTLY | 01 | 000000000000000000001111011000 -AT_MOST | 10 | 000000000000000000001111011000 - -**PS: 实际上关于上面的东西了解即可,在实际运用之中只需要记住有三种模式,用 MeasureSpec 的 getSize是获取数值, getMode是获取模式即可。** - -#### 注意: -**如果对View的宽高进行修改了,不要调用*super.onMeasure(widthMeasureSpec,heightMeasureSpec);*要调用*setMeasuredDimension(widthsize,heightsize);* 这个函数。** - -====== - -### 3.确定View大小(onSizeChanged) - 这个函数在视图大小发生改变时调用。 - -**Q: 在测量完View并使用setMeasuredDimension函数之后View的大小基本上已经确定了,那么为什么还要再次确定View的大小呢?** - -**A: 这是因为View的大小不仅由View本身控制,而且受父控件的影响,所以我们在确定View大小的时候最好使用系统提供的onSizeChanged回调函数。** - -onSizeChanged如下: -``` java - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - super.onSizeChanged(w, h, oldw, oldh); - } -``` -可以看出,它又四个参数,分别为 宽度,高度,上一次宽度,上一次高度。 - -这个函数比较简单,我们只需关注 宽度(w), 高度(h) 即可,这两个参数就是View最终的大小。 - -========= - -### 4.确定子View布局位置(onLayout) - -**确定布局的函数是onLayout,它用于确定子View的位置,在自定义ViewGroup中会用到,他调用的是子View的layout函数。** - - 在自定义ViewGroup中,onLayout一般是循环取出子View,然后经过计算得出各个子View位置的坐标值,然后用以下函数设置子View位置。 - -``` java - child.layout(l, t, r, b); -``` -四个参数分别为: - -名称 | 说明 | 对应的函数 ----- | -------------------------- | --- -l | View左侧距父View左侧的距离 | getLeft(); -t | View顶部距父View顶部的距离 | getTop(); -r | View右侧距父View左侧的距离 | getRight(); -b | View底部距父View顶部的距离 | getBottom(); - -具体可以参考 [坐标系](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Base/%5B1%5DCoordinateSystem.md) 这篇文章。 - -![](http://ww2.sinaimg.cn/large/005Xtdi2gw1f1qzqwvkkbj308c0dwgm9.jpg) - - PS:关于onLayout这个函数在讲解自定义ViewGroup的时候会详细讲解。 - - -======== - -### 5.绘制内容(onDraw) - - onDraw是实际绘制的部分,也就是我们真正关心的部分,使用的是Canvas绘图。 -``` java - @Override - protected void onDraw(Canvas canvas) { - super.onDraw(canvas); - } -``` -关于Canvas绘图是本章节的重点,会分几篇文章进行详细讲解,敬请期待OwO。 - -====== - -### 6.对外提供操作方法和监听回调 - 自定义完View之后,一般会对外暴露一些接口,用于控制View的状态等,或者监听View的变化. - - 本内容会在后续文章中以实例的方式进讲解。 - -************ - -## 三.重点知识梳理 - -### 自定义View分类 - -> PS :实际上ViewGroup是View的一个子类。 - -类别 | 继承自 | 特点 ---------- | --------------------- | ------------ -View | View SurfaceView 等 | 不含子View -ViewGroup | ViewGroup xxLayout等 | 包含子View - -### 自定义View流程: -步骤 | 关键字 | 作用 ----- | ------------- | ------------- - 1 | 构造函数 | View初始化 - 2 | onMeasure | 测量View大小 - 3 | onSizeChanged | 确定View大小 - 4 | onLayout | 确定子View布局(自定义View包含子View时有用) - 5 | onDraw | 实际绘制内容 - 6 | 提供接口 | 控制View或监听View某些状态。 - - - -## About Me - -### 作者微博: @GcsSloop - - - - -## 参考资料: -[View](http://developer.android.com/reference/android/view/View.html)
-[ViewGroup](http://developer.android.com/reference/android/view/ViewGroup.html)
-[View.MeasureSpec](http://developer.android.com/reference/android/view/View.MeasureSpec.html)
-[onMeasure,MeasureSpec源码 流程 思路详解](http://blog.csdn.net/a396901990/article/details/36475213)
-
-[Android中自定义样式与View的构造函数中的第三个参数defStyle的意义](http://www.cnblogs.com/angeldevil/p/3479431.html)
-[android view构造函数研究](http://blog.csdn.net/z103594643/article/details/6755017)
-[Android View构造方法第三参数使用方法详解](http://blog.csdn.net/mybeta/article/details/39993449)
-
-[Android 自定义View onMeasure方法的实现](http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1102/1891.html)
-[Android API指南(二)自定义控件02之 onMeasure](http://wangkuiwu.github.io/2014/06/20/View-OnMeasure/)
-[Android中View的绘制过程 onMeasure方法简述](http://www.cnblogs.com/mengdd/p/3332882.html)
- -
-
diff --git a/CustomView/Advance/[2]Canvas_BasicGraphics.md b/CustomView/Advance/[2]Canvas_BasicGraphics.md deleted file mode 100644 index 0eacbedf..00000000 --- a/CustomView/Advance/[2]Canvas_BasicGraphics.md +++ /dev/null @@ -1,541 +0,0 @@ -# Canvas之绘制基本形状 - -### 作者微博: [@GcsSloop](http://weibo.com/GcsSloop) -### [【本系列相关文章】](https://github.com/GcsSloop/AndroidNote/tree/master/CustomView) - -在上一篇[自定义View分类与流程](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B1%5DCustomViewProcess.md)中我们了解自定义View相关的基本知识,不过,这些东西依旧还是理论,并不能**拿来(zhuang)用(B)**, 这一次我们就了解一些**能(zhaung)用(B)**的东西。 - -在本篇文章中,我们先了解Canvas的基本用法,最后用一个小示例来结束本次教程。 - -## 一.Canvas简介 - -Canvas我们可以称之为画布,能够在上面绘制各种东西,是安卓平台2D图形绘制的基础,非常强大。 - -**一般来说,比较基础的东西有两大特点:
- 1.可操作性强:由于这些是构成上层的基础,所以可操作性必然十分强大。
- 2.比较难用:各种方法太过基础,想要完美的将这些操作组合起来有一定难度。** - -不过不必担心,本系列文章不仅会介绍到Canvas的操作方法,还会简单介绍一些设计思路和技巧。 - -## 二.Canvas的常用操作速查表 - -操作类型 | 相关API | 备注 ---- | --- | --- -绘制颜色 | drawColor, drawRGB, drawARGB | 使用单一颜色填充整个画布 -绘制基本形状 | drawPoint, drawPoints, drawLine, drawLines, drawRect, drawRoundRect, drawOval, drawCircle, drawArc | 依次为 点、线、矩形、圆角矩形、椭圆、圆、圆弧 -绘制图片 | drawBitmap, drawPicture | 绘制位图和图片 -绘制文本 | drawText, drawPosText, drawTextOnPath | 依次为 绘制文字、绘制文字时指定每个文字位置、根据路径绘制文字 -绘制路径 | drawPath | 绘制路径,绘制贝塞尔曲线时也需要用到该函数 -顶点操作 | drawVertices, drawBitmapMesh | 通过对顶点操作可以使图像形变,drawVertices直接对画布作用、 drawBitmapMesh只对绘制的Bitmap作用 -画布剪裁 | clipPath, clipRect | 设置画布的显示区域 -画布快照 | save, restore, saveLayerXxx, restoreToCount, getSaveCount | 依次为 保存当前状态、 回滚到上一次保存的状态、 保存图层状态、 回滚到指定状态、 获取保存次数 -画布变换 | translate, scale, rotate, skew | 依次为 位移、缩放、 旋转、倾斜 -Matrix(矩阵) | getMatrix, setMatrix, concat | 实际画布的位移,缩放等操作的都是图像矩阵Matrix,只不过Matrix比较难以理解和使用,故封装了一些常用的方法。 - -> PS: Canvas常用方法在上面表格中已经全部列出了,当然还存在一些其他的方法未列出,具体可以参考官方文档 [Canvas](http://developer.android.com/reference/android/graphics/Canvas.html) - -****** - -## 三.Canvas详解 - -本篇内容主要讲解如何利用Canvas绘制基本图形。 - - -### 绘制颜色: - -绘制颜色是填充整个画布,常用于绘制底色。 -``` java - canvas.drawColor(Color.BLUE); //绘制蓝色 -``` - - - -> 关于颜色的更多资料请参考[基础篇_颜色](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView%2FBase%2F%5B3%5DColor.md) - -****** - -### 创建画笔: -要想绘制内容,首先需要先创建一个画笔,如下: -``` java - // 1.创建一个画笔 - private Paint mPaint = new Paint(); - - // 2.初始化画笔 - private void initPaint() { - mPaint.setColor(Color.BLACK); //设置画笔颜色 - mPaint.setStyle(Paint.Style.FILL); //设置画笔模式为填充 - mPaint.setStrokeWidth(10f); //设置画笔宽度为10px - } - - // 3.在构造函数中初始化 - public SloopView(Context context, AttributeSet attrs) { - super(context, attrs); - initPaint(); - } -``` -在创建完画笔之后,就可以在Canvas中绘制各种内容了。 - -****** - -### 绘制点: - -可以绘制一个点,也可以绘制一组点,如下: -``` java - canvas.drawPoint(200, 200, mPaint); //在坐标(200,200)位置绘制一个点 - canvas.drawPoints(new float[]{ //绘制一组点,坐标位置由float数组指定 - 500,500, - 500,600, - 500,700 - },mPaint); -``` -关于坐标原点默认在左上角,水平向右为x轴增大方向,竖直向下为y轴增大方向。 - -> 更多参考这里 [基础篇_坐标系](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView%2FBase%2F%5B1%5DCoordinateSystem.md) - - - - -****** - -### 绘制直线: -绘制直线需要两个点,初始点和结束点,同样绘制直线也可以绘制一条或者绘制一组: -``` java - canvas.drawLine(300,300,500,600,mPaint); // 在坐标(300,300)(500,600)之间绘制一条直线 - canvas.drawLines(new float[]{ // 绘制一组线 每四数字(两个点的坐标)确定一条线 - 100,200,200,200, - 100,300,200,300 - },mPaint); -``` - - - - -****** - -### 绘制矩形: -确定确定一个矩形最少需要四个数据,就是**对角线的两个点**的坐标值,这里一般采用**左上角和右下角**的两个点的坐标。 - -关于绘制矩形,Canvas提供了三种重载方法,第一种就是提供**四个数值(矩形左上角和右下角两个点的坐标)来确定一个矩形**进行绘制。 -其余两种是先将矩形封装为**Rect或RectF**(实际上仍然是用两个坐标点来确定的矩形),然后传递给Canvas绘制,如下: - -``` java - // 第一种 - canvas.drawRect(100,100,800,400,mPaint); - - // 第二种 - Rect rect = new Rect(100,100,800,400); - canvas.drawRect(rect,mPaint); - - // 第三种 - RectF rectF = new RectF(100,100,800,400); - canvas.drawRect(rectF,mPaint); -``` -以上三种方法所绘制出来的结果是完全一样的。 - - - -看到这里,相信很多观众会产生一个疑问,为什么会有Rect和RectF两种?两者有什么区别吗? - -答案当然是存在区别的,**两者最大的区别就是精度不同,Rect是int(整形)的,而RectF是float(单精度浮点型)的**。除了精度不同,两种提供的方法也稍微存在差别,在这里我们暂时无需关注,想了解更多参见官方文档 [Rect](http://developer.android.com/reference/android/graphics/Rect.html) 和 [RectF](http://developer.android.com/reference/android/graphics/RectF.html) - -****** - -### 绘制圆角矩形: -绘制圆角矩形也提供了两种重载方式,如下: -``` java - // 第一种 - RectF rectF = new RectF(100,100,800,400); - canvas.drawRoundRect(rectF,30,30,mPaint); - - // 第二种 - canvas.drawRoundRect(100,100,800,400,30,30,mPaint); -``` -上面两种方法绘制效果也是一样的,但鉴于第二种方法在API21的时候才添加上,所以我们一般使用的都是第一种。 - - - -下面简单解析一下圆角矩形的几个必要的参数的意思。 - -很明显可以看出,第二种方法前四个参数和第一种方法的RectF作用是一样的,都是为了确定一个矩形,最后一个参数Paint是画笔,无需多说,**与矩形相比,圆角矩形多出来了两个参数rx 和 ry**,这两个参数是干什么的呢? - -稍微分析一下,既然是圆角矩形,他的角肯定是圆弧(圆形的一部分),**我们一般用什么确定一个圆形呢?** - -答案是**圆心 和 半径,其中圆心用于确定位置,而半径用于确定大小**。
- -由于矩形位置已经确定,所以其边角位置也是确定的,那么确定位置的参数就可以省略,只需要用半径就能描述一个圆弧了。
- -但是,**半径只需要一个参数,但这里怎么会有两个呢?**
- -好吧,让你发现了,**这里圆角矩形的角实际上不是一个正圆的圆弧,而是椭圆的圆弧,这里的两个参数实际上是椭圆的两个半径**,他们看起来个如下图:
- -![](http://ww3.sinaimg.cn/large/005Xtdi2jw1f2748fjw2bj308c0dwmx8.jpg) - -**红线标注的 rx 与 ry 就是两个半径,也就是相比绘制矩形多出来的那两个参数。** - -我们了解到原理后,就可以为所欲为了,通过计算可知我们上次绘制的矩形宽度为700,高度为300,当你让 rx大于350(宽度的一半), ry大于150(高度的一半) 时奇迹就出现了, 你会发现圆角矩形变成了一个椭圆, 他们画出来是这样的 ( 为了方便确认我更改了画笔颜色, 同时绘制出了矩形和圆角矩形 ): - -``` java - // 矩形 - RectF rectF = new RectF(100,100,800,400); - - // 绘制背景矩形 - mPaint.setColor(Color.GRAY); - canvas.drawRect(rectF,mPaint); - - // 绘制圆角矩形 - mPaint.setColor(Color.BLUE); - canvas.drawRoundRect(rectF,700,400,mPaint); -``` - - - -其中灰色部分是我们所选定的矩形,而里面的圆角矩形则变成了一个椭圆,实际上在rx为宽度的一半,ry为高度的一半时,刚好是一个椭圆,通过上面我们分析的原理推算一下就能得到,而当rx大于宽度的一半,ry大于高度的一半时,实际上是无法计算出圆弧的,所以drawRoundRect对大于该数值的参数进行了限制(修正),凡是大于一半的参数均按照一半来处理。 - - -****** - -### 绘制椭圆: -相对于绘制圆角矩形,绘制椭圆就简单的多了,因为他只需要一个矩形矩形作为参数: - -``` java - // 第一种 - RectF rectF = new RectF(100,100,800,400); - canvas.drawOval(rectF,mPaint); - - // 第二种 - canvas.drawOval(100,100,800,400,mPaint); -``` -同样,以上两种方法效果完全一样,但一般使用第一种。 - - - -绘制椭圆实际上就是绘制一个矩形的内切图形,原理如下,就不多说了: - -![](http://ww2.sinaimg.cn/large/005Xtdi2jw1f274bq1h4rj308c0dwjrl.jpg) - -PS: 如果你传递进来的是一个长宽相等的矩形(即正方形),那么绘制出来的实际上就是一个圆。 - -****** -### 绘制圆: - -绘制圆形也比较简单, 如下: - -``` - canvas.drawCircle(500,500,400,mPaint); // 绘制一个圆心坐标在(500,500),半径为400 的圆。 -``` -绘制圆形有四个参数,前两个是圆心坐标,第三个是半径,最后一个是画笔。 - - - -****** -### 绘制圆弧: - -绘制圆弧就比较神奇一点了,为了理解这个比较神奇的东西,我们先看一下它需要的几个参数: - -``` java -// 第一种 -public void drawArc(@NonNull RectF oval, float startAngle, float sweepAngle, boolean useCenter, @NonNull Paint paint){} - -// 第二种 -public void drawArc(float left, float top, float right, float bottom, float startAngle, - float sweepAngle, boolean useCenter, @NonNull Paint paint) {} -``` - -从上面可以看出,相比于绘制椭圆,绘制圆弧还多了三个参数: - -``` java -startAngle // 开始角度 -sweepAngle // 扫过角度 -useCenter // 是否使用中心 -``` - -通过字面意思我们基本能猜测出来前两个参数(startAngle, sweepAngel)的作用,就是确定角度的起始位置和扫过角度, 不过第三个参数是干嘛的?试一下就知道了,上代码: - -``` - RectF rectF = new RectF(100,100,800,400); - // 绘制背景矩形 - mPaint.setColor(Color.GRAY); - canvas.drawRect(rectF,mPaint); - - // 绘制圆弧 - mPaint.setColor(Color.BLUE); - canvas.drawArc(rectF,0,90,false,mPaint); - - //------------------------------------- - - RectF rectF2 = new RectF(100,600,800,900); - // 绘制背景矩形 - mPaint.setColor(Color.GRAY); - canvas.drawRect(rectF2,mPaint); - - // 绘制圆弧 - mPaint.setColor(Color.BLUE); - canvas.drawArc(rectF2,0,90,true,mPaint); -``` - -上述代码实际上是绘制了一个起始角度为0度,扫过90度的圆弧,两者的区别就是是否使用了中心点,结果如下: - - - -可以发现使用了中心点之后绘制出来类似于一个扇形,而不使用中心点则是圆弧起始点和结束点之间的连线加上圆弧围成的图形。这样中心点这个参数的作用就很明显了,不必多说想必大家试一下就明白了。 另外可以关于角度可以参考一下这篇文章: [角度与弧度](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView%2FBase%2F%5B2%5DAngleAndRadian.md) - -相比于使用椭圆,我们还是使用正圆比较多的,使用正圆展示一下效果: - -``` - RectF rectF = new RectF(100,100,800,400); - // 绘制背景矩形 - mPaint.setColor(Color.GRAY); - canvas.drawRect(rectF,mPaint); - - // 绘制圆弧 - mPaint.setColor(Color.BLUE); - canvas.drawArc(rectF,0,90,false,mPaint); - - //------------------------------------- - - RectF rectF2 = new RectF(100,600,800,900); - // 绘制背景矩形 - mPaint.setColor(Color.GRAY); - canvas.drawRect(rectF2,mPaint); - - // 绘制圆弧 - mPaint.setColor(Color.BLUE); - canvas.drawArc(rectF2,0,90,true,mPaint); -``` - - -****** -### 简要介绍Paint - -看了上面这么多,相信有一部分人会产生一个疑问,如果我想绘制一个圆,只要边不要里面的颜色怎么办? - -很简单,绘制的**基本形状由Canvas确定**,但绘制出来的**颜色,具体效果则由Paint确定**。 - -如果你注意到了的话,在一开始我们设置画笔样式的时候是这样的: - -``` java - mPaint.setStyle(Paint.Style.FILL); //设置画笔模式为填充 -``` - -为了展示方便,容易看出效果,之前使用的模式一直为填充模式,实际上画笔有三种模式,如下: - -``` java -STROKE //描边 -FILL //填充 -FILL_AND_STROKE //描边加填充 -``` - -为了区分三者效果我们做如下实验: - -``` - Paint paint = new Paint(); - paint.setColor(Color.BLUE); - paint.setStrokeWidth(40); //为了实验效果明显,特地设置描边宽度非常大 - - // 描边 - paint.setStyle(Paint.Style.STROKE); - canvas.drawCircle(200,200,100,paint); - - // 填充 - paint.setStyle(Paint.Style.FILL); - canvas.drawCircle(200,500,100,paint); - - // 描边加填充 - paint.setStyle(Paint.Style.FILL_AND_STROKE); - canvas.drawCircle(200, 800, 100, paint); -``` - - - -一图胜千言,通过以上实验我们可以比较明显的看出三种模式的区别,如果只需要边缘不需要填充内容的话只需要设置模式为描边(STROKE)即可。 - -其实关于Paint的内容也是有不少的,这些只是冰山一角,在后续内容中会详细的讲解Paint。 - -****** -## 小示例 - -### 简要介绍画布的操作: - -> 画布操作详细内容会在下一篇文章中讲解, 不是本文重点,但以下示例中可能会用到,所以此处简要介绍一下。 - -相关操作 | 简要介绍 -----------|------------------------ -save | 保存当前画布状态 -restore | 回滚到上一次保存的状态 -translate | 相对于当前位置位移 -rotate | 旋转 - -### 制作一个饼状图 - -在展示百分比数据的时候经常会用到饼状图,像这样: - -![](http://ww2.sinaimg.cn/large/005Xtdi2jw1f274gmnlk3j308c0dwglq.jpg) - -### 简单分析 - -其实根据我们上面的知识已经能自己制作一个饼状图了。不过制作东西最重要的不是制作结果,而是制作思路。 -相信我贴上代码大家一看就立刻明白了,非常简单的东西。不过嘛,咱们还是想了解一下制作思路: - -先分析饼状图的构成,非常明显,饼状图就是一个又一个的扇形构成的,每个扇形都有不同的颜色,对应的有名字,数据和百分比。 - -经以上信息可以得出饼状图的最基本数据应包括:名字 数据值 百分比 对应的角度 颜色。 - - -用户关心的数据 : 名字 数据值 百分比
-需要程序计算的数据: 百分比 对应的角度
-其中颜色这一项可以用户指定也可以用程序指定(我们这里采用程序指定)。
-
- -### 封装数据: -``` java -public class PieData { - // 用户关心数据 - private String name; // 名字 - private float value; // 数值 - private float percentage; // 百分比 - - // 非用户关心数据 - private int color = 0; // 颜色 - private float angle = 0; // 角度 - - public PieData(@NonNull String name, @NonNull float value) { - this.name = name; - this.value = value; - } -} -``` -PS: 以上省略了get set方法 - -### 自定义View: -先按照自定义View流程梳理一遍(确定各个步骤应该做的事情): - -步骤 | 关键字 | 作用 -:---:|-------------- | ----------------------- - 1 | 构造函数 | 初始化(初始化画笔Paint) - 2 | onMeasure | 测量View的大小(暂时不用关心) - 3 | onSizeChanged | 确定View大小(记录当前View的宽高) - 4 | onLayout | 确定子View布局(无子View,不关心) - 5 | onDraw | 实际绘制内容(绘制饼状图) - 6 | 提供接口 | 提供接口(提供设置数据的接口) - -代码如下: - -``` java -public class PieView extends View { - // 颜色表 - private int[] mColors = {0xFFCCFF00, 0xFF6495ED, 0xFFE32636, 0xFF800000, 0xFF808000, 0xFFFF8C69, 0xFF808080, - 0xFFE6B800, 0xFF7CFC00}; - // 饼状图初始绘制角度 - private float mStartAngle = 0; - // 数据 - private ArrayList mData; - // 宽高 - private int mWidth, mHeight; - // 画笔 - private Paint mPaint = new Paint(); - - public PieView(Context context) { - this(context, null); - } - - public PieView(Context context, AttributeSet attrs) { - super(context, attrs); - mPaint.setStyle(Paint.Style.FILL); - mPaint.setAntiAlias(true); - } - - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - super.onSizeChanged(w, h, oldw, oldh); - mWidth = w; - mHeight = h; - } - - @Override - protected void onDraw(Canvas canvas) { - super.onDraw(canvas); - if (null == mData) - return; - float currentStartAngle = mStartAngle; // 当前起始角度 - canvas.translate(mWidth / 2, mHeight / 2); // 将画布坐标原点移动到中心位置 - float r = (float) (Math.min(mWidth, mHeight) / 2 * 0.8); // 饼状图半径 - RectF rect = new RectF(-r, -r, r, r); // 饼状图绘制区域 - - for (int i = 0; i < mData.size(); i++) { - PieData pie = mData.get(i); - mPaint.setColor(pie.getColor()); - canvas.drawArc(rect, currentStartAngle, pie.getAngle(), true, mPaint); - currentStartAngle += pie.getAngle(); - } - - } - - // 设置起始角度 - public void setStartAngle(int mStartAngle) { - this.mStartAngle = mStartAngle; - invalidate(); // 刷新 - } - - // 设置数据 - public void setData(ArrayList mData) { - this.mData = mData; - initDate(mData); - invalidate(); // 刷新 - } - - // 初始化数据 - private void initDate(ArrayList mData) { - if (null == mData || mData.size() == 0) // 数据有问题 直接返回 - return; - - float sumValue = 0; - for (int i = 0; i < mData.size(); i++) { - PieData pie = mData.get(i); - - sumValue += pie.getValue(); //计算数值和 - - int j = i % mColors.length; //设置颜色 - pie.setColor(mColors[j]); - } - - float sumAngle = 0; - for (int i = 0; i < mData.size(); i++) { - PieData pie = mData.get(i); - - float percentage = pie.getValue() / sumValue; // 百分比 - float angle = percentage * 360; // 对应的角度 - - pie.setPercentage(percentage); // 记录百分比 - pie.setAngle(angle); // 记录角度大小 - sumAngle += angle; - - Log.i("angle", "" + pie.getAngle()); - } - } -} -``` - -**PS: 在更改了数据需要重绘界面时要调用invalidate()这个函数重新绘制。** - -### 效果图 - - - -> **PS: 这个饼状图并没有添加百分比等数据,仅作为示例使用。** - -## 总结: - - 其实自定义View只要按照流程一步步的走,也是比较容易的。不过里面也有不少坑,这些坑还是自己踩过印象比较深,建议大家不要直接copy源码,自己手打体验一下。 - -## About Me -### 作者微博: @GcsSloop - - - -## 参考资料: - -[View](http://developer.android.com/reference/android/view/View.html)
-[Canvas](http://developer.android.com/reference/android/graphics/Canvas.html)
-[Android Canvas绘图详解](http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2012/1212/703.html)
- -




diff --git a/CustomView/Advance/[3]Canvas_Convert.md b/CustomView/Advance/[3]Canvas_Convert.md deleted file mode 100644 index 5d47a6a9..00000000 --- a/CustomView/Advance/[3]Canvas_Convert.md +++ /dev/null @@ -1,448 +0,0 @@ -# Canvas之画布操作 - -### 作者微博: [@GcsSloop](http://weibo.com/GcsSloop) -### [【本系列相关文章】](https://github.com/GcsSloop/AndroidNote/tree/master/CustomView) - -上一篇[Canvas之绘制基本形状](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B2%5DCanvas_BasicGraphics.md)中我们了解了如何使用Canvas绘制基本图形,本次了解一些基本的画布操作。 - -本来想把画布操作放到后面部分的,但是发现很多图形绘制都离不开画布操作,于是先讲解一下画布的基本操作方法。 - -## 一.Canvas的常用操作速查表 - -操作类型 | 相关API | 备注 ---- | --- | --- -绘制颜色 | drawColor, drawRGB, drawARGB | 使用单一颜色填充整个画布 -绘制基本形状 | drawPoint, drawPoints, drawLine, drawLines, drawRect, drawRoundRect, drawOval, drawCircle, drawArc | 依次为 点、线、矩形、圆角矩形、椭圆、圆、圆弧 -绘制图片 | drawBitmap, drawPicture | 绘制位图和图片 -绘制文本 | drawText, drawPosText, drawTextOnPath | 依次为 绘制文字、绘制文字时指定每个文字位置、根据路径绘制文字 -绘制路径 | drawPath | 绘制路径,绘制贝塞尔曲线时也需要用到该函数 -顶点操作 | drawVertices, drawBitmapMesh | 通过对顶点操作可以使图像形变,drawVertices直接对画布作用、 drawBitmapMesh只对绘制的Bitmap作用 -画布剪裁 | clipPath, clipRect | 设置画布的显示区域 -画布快照 | save, restore, saveLayerXxx, restoreToCount, getSaveCount | 依次为 保存当前状态、 回滚到上一次保存的状态、 保存图层状态、 回滚到指定状态、 获取保存次数 -画布变换 | translate, scale, rotate, skew | 依次为 位移、缩放、 旋转、倾斜 -Matrix(矩阵) | getMatrix, setMatrix, concat | 实际上画布的位移,缩放等操作的都是图像矩阵Matrix, 只不过Matrix比较难以理解和使用,故封装了一些常用的方法。 - -****** -## 二.Canvas基本操作 - -### 1.画布操作 -#### 为什么要有画布操作? - -画布操作可以帮助我们用更加容易理解的方式制作图形。 - -例如: 从坐标原点为起点,绘制一个长度为20dp,与水平线夹角为30度的线段怎么做? - -按照我们通常的想法(*被常年训练出来的数学思维*),就是先使用三角函数计算出线段结束点的坐标,然后调用drawLine即可。 - -然而这是否是被固有思维禁锢了? - -假设我们先绘制一个长度为20dp的水平线,然后将这条水平线旋转30度,则最终看起来效果是相同的,而且不用进行三角函数计算,这样是否更加简单了一点呢? - -**合理的使用画布操作可以帮助你用更容易理解的方式创作你想要的效果,这也是画布操作存在的原因。** - -**PS: 所有的画布操作都只影响后续的绘制,对之前已经绘制过的内容没有影响。** - -***** -#### ⑴位移(translate) - - translate是坐标系的移动,可以为图形绘制选择一个合适的坐标系。 - **请注意,位移是基于当前位置移动,而不是每次基于屏幕左上角的(0,0)点移动**,如下: -``` java - // 省略了创建画笔的代码 - - // 在坐标原点绘制一个黑色圆形 - mPaint.setColor(Color.BLACK); - canvas.translate(200,200); - canvas.drawCircle(0,0,100,mPaint); - - // 在坐标原点绘制一个蓝色圆形 - mPaint.setColor(Color.BLUE); - canvas.translate(200,200); - canvas.drawCircle(0,0,100,mPaint); -``` - - - -我们首先将坐标系移动一段距离绘制一个圆形,之后再移动一段距离绘制一个圆形,两次移动是可叠加的。 - -***** -#### ⑵缩放(scale) -缩放提供了两个方法,如下: -``` java - public void scale (float sx, float sy) - - public final void scale (float sx, float sy, float px, float py) -``` -这两个方法中前两个参数是相同的分别为x轴和y轴的缩放比例。而第二种方法比前一种多了两个参数,用来控制缩放中心位置的。 - -缩放比例(sx,sy)取值范围详解: - -取值范围(n)| 说明 ---------- | ------ -[-∞, -1) | 先根据缩放中心放大n倍,再根据中心轴进行翻转 --1 | 根据缩放中心轴进行翻转 -(-1, 0) | 先根据缩放中心缩小到n,再根据中心轴进行翻转 -0 | 不会显示,若sx为0,则宽度为0,不会显示,sy同理 -(0, 1) | 根据缩放中心缩小到n -1 | 没有变化 -(1, +∞) | 根据缩放中心放大n倍 - -如果在缩放时稍微注意一下就会发现缩放的中心默认为坐标原点,而缩放中心轴就是坐标轴,如下: - -``` java - // 将坐标系原点移动到画布正中心 - canvas.translate(mWidth / 2, mHeight / 2); - - RectF rect = new RectF(0,-400,400,0); // 矩形区域 - - mPaint.setColor(Color.BLACK); // 绘制黑色矩形 - canvas.drawRect(rect,mPaint); - - canvas.scale(0.5f,0.5f); // 画布缩放 - - mPaint.setColor(Color.BLUE); // 绘制蓝色矩形 - canvas.drawRect(rect,mPaint); -``` -(为了更加直观,我添加了一个坐标系,可以比较明显的看出,缩放中心就是坐标原点) - - - -接下来我们使用第二种方法让缩放中心位置稍微改变一下,如下: -``` java - // 将坐标系原点移动到画布正中心 - canvas.translate(mWidth / 2, mHeight / 2); - - RectF rect = new RectF(0,-400,400,0); // 矩形区域 - - mPaint.setColor(Color.BLACK); // 绘制黑色矩形 - canvas.drawRect(rect,mPaint); - - canvas.scale(0.5f,0.5f,200,0); // 画布缩放 <-- 缩放中心向右偏移了200个单位 - - mPaint.setColor(Color.BLUE); // 绘制蓝色矩形 - canvas.drawRect(rect,mPaint); -``` -(图中用箭头指示的就是缩放中心。) - - - -前面两个示例缩放的数值都是正数,按照表格中的说明,**当缩放比例为负数的时候会根据缩放中心轴进行翻转**,下面我们就来实验一下: - -``` java - // 将坐标系原点移动到画布正中心 - canvas.translate(mWidth / 2, mHeight / 2); - - RectF rect = new RectF(0,-400,400,0); // 矩形区域 - - mPaint.setColor(Color.BLACK); // 绘制黑色矩形 - canvas.drawRect(rect,mPaint); - - - canvas.scale(-0.5f,-0.5f); // 画布缩放 - - mPaint.setColor(Color.BLUE); // 绘制蓝色矩形 - canvas.drawRect(rect,mPaint); -``` - - -> 为了效果明显,这次我不仅添加了坐标系而且对矩形中几个重要的点进行了标注,具有相同字母标注的点是一一对应的。 - -由于本次未对缩放中心进行偏移,所有默认的缩放中心就是坐标原点,中心轴就是x轴和y轴。 - -本次缩放可以看做是先根据缩放中心(坐标原点)缩放到原来的0.5倍,然后分别按照x轴和y轴进行翻转。 - -``` java - // 将坐标系原点移动到画布正中心 - canvas.translate(mWidth / 2, mHeight / 2); - - RectF rect = new RectF(0,-400,400,0); // 矩形区域 - - mPaint.setColor(Color.BLACK); // 绘制黑色矩形 - canvas.drawRect(rect,mPaint); - - - canvas.scale(-0.5f,-0.5f,200,0); // 画布缩放 <-- 缩放中心向右偏移了200个单位 - - mPaint.setColor(Color.BLUE); // 绘制蓝色矩形 - canvas.drawRect(rect,mPaint); -``` - - -> 添加了这么多的辅助内容,希望大家能够看懂。 - -本次对缩放中心点y轴坐标进行了偏移,故中心轴也向右偏移了。 - - -PS:和位移(translate)一样,缩放也是可以叠加的。 -``` java - canvas.scale(0.5f,0.5f); - canvas.scale(0.5f,0.1f); -``` -调用两次缩放则 x轴实际缩放为0.5x0.5=0.25 y轴实际缩放为0.5x0.1=0.05 - -下面我们利用这一特性制作一个有趣的图形。 -``` java - // 将坐标系原点移动到画布正中心 - canvas.translate(mWidth / 2, mHeight / 2); - - RectF rect = new RectF(-400,-400,400,400); // 矩形区域 - - for (int i=0; i<=20; i++) - { - canvas.scale(0.9f,0.9f); - canvas.drawRect(rect,mPaint); - } -``` - - - -***** -#### ⑶旋转(rotate) -旋转提供了两种方法: -``` java - public void rotate (float degrees) - - public final void rotate (float degrees, float px, float py) -``` -和缩放一样,第二种方法多出来的两个参数依旧是控制旋转中心点的。 - -默认的旋转中心依旧是坐标原点: -``` java - // 将坐标系原点移动到画布正中心 - canvas.translate(mWidth / 2, mHeight / 2); - - RectF rect = new RectF(0,-400,400,0); // 矩形区域 - - mPaint.setColor(Color.BLACK); // 绘制黑色矩形 - canvas.drawRect(rect,mPaint); - - canvas.rotate(180); // 旋转180度 <-- 默认旋转中心为原点 - - mPaint.setColor(Color.BLUE); // 绘制蓝色矩形 - canvas.drawRect(rect,mPaint); -``` - - - -改变旋转中心位置: -``` java - // 将坐标系原点移动到画布正中心 - canvas.translate(mWidth / 2, mHeight / 2); - - RectF rect = new RectF(0,-400,400,0); // 矩形区域 - - mPaint.setColor(Color.BLACK); // 绘制黑色矩形 - canvas.drawRect(rect,mPaint); - - canvas.rotate(180,200,0); // 旋转180度 <-- 旋转中心向右偏移200个单位 - - mPaint.setColor(Color.BLUE); // 绘制蓝色矩形 - canvas.drawRect(rect,mPaint); -``` - - - -好吧,旋转也是可叠加的 -``` java - canvas.rotate(180); - canvas.rotate(20); -``` -调用两次旋转,则实际的旋转角度为180+20=200度。 - -为了演示这一个效果,我做了一个不明觉厉的东西: -``` java - // 将坐标系原点移动到画布正中心 - canvas.translate(mWidth / 2, mHeight / 2); - - canvas.drawCircle(0,0,400,mPaint); // 绘制两个圆形 - canvas.drawCircle(0,0,380,mPaint); - - for (int i=0; i<=360; i+=10){ // 绘制圆形之间的连接线 - canvas.drawLine(0,380,0,400,mPaint); - canvas.rotate(10); - } -``` - - -***** -#### ⑷倾斜(skew) - -skew这里翻译为倾斜,有的地方也叫错切。 - -倾斜只提供了一种方法: -``` java - public void skew (float sx, float sy) -``` -参数含义:
-float sx:将画布在x方向上倾斜相应的角度,sx倾斜角度的tan值,
-float sy:将画布在y轴方向上倾斜相应的角度,sy为倾斜角度的tan值.
- -示例: -``` java - // 将坐标系原点移动到画布正中心 - canvas.translate(mWidth / 2, mHeight / 2); - - RectF rect = new RectF(0,0,200,200); // 矩形区域 - - mPaint.setColor(Color.BLACK); // 绘制黑色矩形 - canvas.drawRect(rect,mPaint); - - canvas.skew(1,0); // 在x轴倾斜45度 <-- tan45 = 1 - - mPaint.setColor(Color.BLUE); // 绘制蓝色矩形 - canvas.drawRect(rect,mPaint); -``` - - -如你所想,倾斜也是可叠加的,不过请注意,调用次序不同绘制结果也会不同 -``` java - // 将坐标系原点移动到画布正中心 - canvas.translate(mWidth / 2, mHeight / 2); - - RectF rect = new RectF(0,0,200,200); // 矩形区域 - - mPaint.setColor(Color.BLACK); // 绘制黑色矩形 - canvas.drawRect(rect,mPaint); - - canvas.skew(1,0); // 在x轴倾斜45度 <-- tan45 = 1 - canvas.skew(0,1); // 在y轴倾斜45度 <-- tan45 = 1 - - mPaint.setColor(Color.BLUE); // 绘制蓝色矩形 - canvas.drawRect(rect,mPaint); -``` - - - -***** -#### ⑸快照(save)和回滚(restore) - - -Q: 为什存在快照与回滚
-A:画布的操作是不可逆的,而且很多画布操作会影响后续的步骤,例如第一个例子,两个圆形都是在坐标原点绘制的,而因为坐标系的移动绘制出来的实际位置不同。所以会对画布的一些状态进行保存和回滚。 -
- -与之相关的API: - -相关API | 简介 ---- | --- -save | 把当前的画布的状态进行保存,然后放入特定的栈中 -saveLayerXxx | 新建一个图层,并放入特定的栈中 -restore | 把栈中最顶层的画布状态取出来,并按照这个状态恢复当前的画布 -restoreToCount| 弹出指定位置及其以上所有的状态,并按照指定位置的状态进行恢复 -getSaveCount | 获取栈中内容的数量(即保存次数) - -下面对其中的一些概念和方法进行分析: - -##### 状态栈: -其实这个栈我也不知道叫什么名字,暂时叫做状态栈吧,它看起来像下面这样: - -![](http://ww4.sinaimg.cn/large/005Xtdi2jw1f2gfqmu2sgj308c0dwmxw.jpg) - -这个栈可以存储画布状态和图层状态。 - -Q:什么是画布和图层?
-A:实际上我们看到的画布是由多个图层构成的,如下图(图片来自网络):
- -![](http://ww1.sinaimg.cn/large/005Xtdi2jw1f2gfrc6fdkj308c0dwglr.jpg) - -实际上我们之前讲解的绘制操作和画布操作都是在默认图层上进行的。
-在通常情况下,使用默认图层就可满足需求,但是如果需要绘制比较复杂的内容,如地图(地图可以有多个地图层叠加而成,比如:政区层,道路层,兴趣点层)等,则分图层绘制比较好一些。
-你可以把这些图层看做是一层一层的玻璃板,你在每层的玻璃板上绘制内容,然后把这些玻璃板叠在一起看就是最终效果。 -
- -##### SaveFlags - -数据类型 | 名称 | 简介 ---- | --- | --- -int | ALL_SAVE_FLAG | 默认,保存全部状态 -int | CLIP_SAVE_FLAG | 保存剪辑区 -int | CLIP_TO_LAYER_SAVE_FLAG | 剪裁区作为图层保存 -int | FULL_COLOR_LAYER_SAVE_FLAG | 保存图层的全部色彩通道 -int | HAS_ALPHA_LAYER_SAVE_FLAG | 保存图层的alpha(不透明度)通道 -int | MATRIX_SAVE_FLAG | 保存Matrix信息(translate, rotate, scale, skew) - -##### save -save 有两种方法: -``` java - // 保存全部状态 - public int save () - - // 根据saveFlags参数保存一部分状态 - public int save (int saveFlags) -``` -可以看到第二种方法比第一种多了一个saveFlags参数,使用这个参数可以只保存一部分状态,更加灵活,这个saveFlags参数具体可参考上面表格中的内容。 - -每调用一次save方法,都会在栈顶添加一条状态信息,以上面状态栈图片为例,再调用一次save则会在第5次上面载添加一条状态。 - -#### saveLayerXxx -saveLayerXxx有比较多的方法: -``` java -// 无图层alpha(不透明度)通道 -public int saveLayer (RectF bounds, Paint paint) -public int saveLayer (RectF bounds, Paint paint, int saveFlags) -public int saveLayer (float left, float top, float right, float bottom, Paint paint) -public int saveLayer (float left, float top, float right, float bottom, Paint paint, int saveFlags) - -// 有图层alpha(不透明度)通道 -public int saveLayerAlpha (RectF bounds, int alpha) -public int saveLayerAlpha (RectF bounds, int alpha, int saveFlags) -public int saveLayerAlpha (float left, float top, float right, float bottom, int alpha) -public int saveLayerAlpha (float left, float top, float right, float bottom, int alpha, int saveFlags) -``` -注意:saveLayerXxx方法会让你花费更多的时间去渲染图像(图层多了相互之间叠加会导致计算量成倍增长),使用前请谨慎,如果可能,尽量避免使用。 - -使用saveLayerXxx方法,也会将图层状态也放入状态栈中,同样使用restore方法进行恢复。 - -这个暂时不过多讲述,如果以后用到详细讲解。(因为这里面东西也有不少啊QAQ) - -##### restore -状态回滚,就是从栈顶取出一个状态然后根据内容进行恢复。 - -同样以上面状态栈图片为例,调用一次restore方法则将状态栈中第5次取出,根据里面保存的状态进行状态恢复。 - -##### restoreToCount -弹出指定位置以及以上所有状态,并根据指定位置状态进行恢复。 - -以上面状态栈图片为例,如果调用restoreToCount(2) 则会弹出 2 3 4 5 的状态,并根据第2次保存的状态进行恢复。 - -##### getSaveCount -获取保存的次数,即状态栈中保存状态的数量,以上面状态栈图片为例,使用该函数的返回值为5。 - -不过请注意,该函数的最小返回值为1,即使弹出了所有的状态,返回值依旧为1,代表默认状态。 - -##### 常用格式 -虽然关于状态的保存和回滚啰嗦了不少,不过大多数情况下只需要记住下面的步骤就可以了: -``` java - save(); //保存状态 - ... //具体操作 - restore(); //回滚到之前的状态 -``` -这种方式也是最简单和最容易理解的使用方法。 - - - -****** -## 三.总结 - -如本文一开始所说,合理的使用画布操作可以帮助你用更容易理解的方式创作你想要的效果。 - -(,,• ₃ •,,) - -PS: 由于本人英文水平有限,某些地方可能存在误解或词语翻译不准确,如果你对此有疑问可以提交Issues进行反馈。 - -## About Me -### 作者微博: @GcsSloop - - - -****** -## 四.参考资料 - -[Canvas](http://developer.android.com/reference/android/graphics/Canvas.html)
-[canvas变换与操作](http://blog.csdn.net/harvic880925/article/details/39080931)
-[Canvas之translate、scale、rotate、skew方法讲解](http://blog.csdn.net/tianjian4592/article/details/45234419)
-[Canvas的save(),saveLayer()和restore()浅谈](http://www.cnblogs.com/liangstudyhome/p/4143498.html)
-[Graphics->Layers](http://www.programgo.com/article/72302404062/;jsessionid=8E62016408BFFB21D46F9C878A49D8EE)
-[]()
-[]()
- diff --git a/CustomView/Advance/[4]Canvas_PictureText.md b/CustomView/Advance/[4]Canvas_PictureText.md deleted file mode 100644 index 401d21a4..00000000 --- a/CustomView/Advance/[4]Canvas_PictureText.md +++ /dev/null @@ -1,506 +0,0 @@ -# Canvas之图片文字 - -### 作者微博: [@GcsSloop](http://weibo.com/GcsSloop) -### [【本系列相关文章】](https://github.com/GcsSloop/AndroidNote/tree/master/CustomView) - -在上一篇文章[Canvas之画布操作](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B3%5DCanvas_Convert.md)中我们了解了画布的一些基本操作方法,本次了解一些绘制图片文字相关的内容。如果你对前几篇文章讲述的内容熟练掌握的话,那么恭喜你,本篇结束之后,大部分的自定义View已经难不倒你了,当然了,这并不是终点,接下来还会有更加炫酷的技能。 - -## 一.Canvas的常用操作速查表 - -操作类型 | 相关API | 备注 ----------|---------|----------- -绘制颜色 | drawColor, drawRGB, drawARGB | 使用单一颜色填充整个画布 -绘制基本形状 | drawPoint, drawPoints, drawLine, drawLines, drawRect, drawRoundRect, drawOval, drawCircle, drawArc | 依次为 点、线、矩形、圆角矩形、椭圆、圆、圆弧 -绘制图片 | drawBitmap, drawPicture | 绘制位图和图片 -绘制文本 | drawText, drawPosText, drawTextOnPath | 依次为 绘制文字、绘制文字时指定每个文字位置、根据路径绘制文字 -绘制路径 | drawPath | 绘制路径,绘制贝塞尔曲线时也需要用到该函数 -顶点操作 | drawVertices, drawBitmapMesh | 通过对顶点操作可以使图像形变,drawVertices直接对画布作用、 drawBitmapMesh只对绘制的Bitmap作用 -画布剪裁 | clipPath, clipRect | 设置画布的显示区域 -画布快照 | save, restore, saveLayerXxx, restoreToCount, getSaveCount | 依次为 保存当前状态、 回滚到上一次保存的状态、 保存图层状态、 回滚到指定状态、 获取保存次数 -画布变换 | translate, scale, rotate, skew | 依次为 位移、缩放、 旋转、倾斜 -Matrix(矩阵) | getMatrix, setMatrix, concat | 实际上画布的位移,缩放等操作的都是图像矩阵Matrix, 只不过Matrix比较难以理解和使用,故封装了一些常用的方法。 - -****** -# 二.Canvas基本操作详解 - -## 1.绘制图片 - -绘制有两种方法,drawPicture(矢量图) 和 drawBitmap(位图),接下来我们一一了解。 - -### (1)drawPicture - -**使用Picture前请关闭硬件加速,以免引起不必要的问题!
使用Picture前请关闭硬件加速,以免引起不必要的问题!
使用Picture前请关闭硬件加速,以免引起不必要的问题!** - -**在AndroidMenifest文件中application节点下添上 android:hardwareAccelerated="false"以关闭整个应用的硬件加速。
更多请参考这里:[Android的硬件加速及可能导致的问题](https://github.com/GcsSloop/AndroidNote/issues/7)** - -关于drawPicture一开始还是挺让人费解的,不过嘛,我们接下来慢慢研究一下它的用途。 - -既然是drawPicture就要了解一下什么是Picture。 顾名思义,Picture的意思是图片。 - -不过嘛,我觉得这么用图片这个名词解释Picture是不合适的,为何这么说?请看其官方文档对[Picture](http://developer.android.com/reference/android/graphics/Picture.html)的解释: - - -A Picture records drawing calls (via the canvas returned by beginRecording) and can then play them back into Canvas (via draw(Canvas) or drawPicture(Picture)).For most content (e.g. text, lines, rectangles), drawing a sequence from a picture can be faster than the equivalent API calls, since the picture performs its playback without incurring any method-call overhead. - - -好吧,我知道很多人对这段鸟语是看不懂的,至于为什么要放在这里,仅仅是为了显得更加专业(偷笑)。 - -**下面我就对这段不明觉厉的鸟语用通俗的话翻译一下:** - -某一天小萌想在朋友面前显摆一下,于是在单杠上来了一个后空翻,动作姿势请参照下图: - - - -朋友都说 恩,很不错。 想再看一遍 (〃ω〃)。ヽ(〃∀〃)ノ。⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄ - -于是小萌又来了一遍,如是几次之后,小萌累的吐血三升。 - -于是小萌机智的想,我何不能用手机将我是飒爽英姿录下来呢,直接保存成为**后空翻.avi** 下次想显摆的时候直接拿出手机,点一下播放就行了,省时省力。 - -小萌被自己的机智深深的折服了,然后Picture就诞生啦。(╯‵□′)╯︵┻━┻掀桌,坑爹呢,这剧情跳跃也忒大了吧。 - - -**好吧,言归正传,这次我们了解的Picture和上文中的录像功能是类似的,只不过我们Picture录的是Canvas中绘制的内容。** - -我们把Canvas绘制点,线,矩形等诸多操作用Picture录制下来,下次需要的时候拿来就能用,使用Picture相比于再次调用绘图API,开销是比较小的,也就是说对于重复的操作可以更加省时省力。 - -**PS:你可以把Picture看作是一个录制Canvas操作的录像机。** - -了解了Picture的概念之后,我们再了解一下Picture的相关方法。 - -相关方法 | 简介 -------------------------------------------------------------|-------------------- -public int getWidth () | 获取宽度 -public int getHeight () | 获取高度 -public Canvas beginRecording (int width, int height) | 开始录制 (返回一个Canvas,在Canvas中所有的绘制都会存储在Picture中) -public void endRecording () | 结束录制 -public void draw (Canvas canvas) | 将Picture中内容绘制到Canvas中 -public static Picture createFromStream (InputStream stream) | (已废弃)通过输入流创建一个Picture -public void writeToStream (OutputStream stream) | (已废弃)将Picture中内容写出到输出流中 - -上面表格中基本上已经列出了Picture的所有方法,其中getWidth和getHeight没什么好说的,最后两个已经废弃也自然就不用关注了,排除了这些方法之后,只剩三个方法了,接下来我们就比较详细的了解一下: - -**很明显,beginRecording 和 endRecording 是成对使用的,一个开始录制,一个是结束录制,两者之间的操作将会存储在Picture中。** - -#### 使用示例: - -**准备工作:** - -录制内容,即将一些Canvas操作用Picture存储起来,录制的内容是不会直接显示在屏幕上的,只是存储起来了而已。 - -``` java - // 1.创建Picture - private Picture mPicture = new Picture(); - ---------------------------------------------------------------- - - // 2.录制内容方法 - private void recording() { - // 开始录制 (接收返回值Canvas) - Canvas canvas = mPicture.beginRecording(500, 500); - // 创建一个画笔 - Paint paint = new Paint(); - paint.setColor(Color.BLUE); - paint.setStyle(Paint.Style.FILL); - - // 在Canvas中具体操作 - // 位移 - canvas.translate(250,250); - // 绘制一个圆 - canvas.drawCircle(0,0,100,paint); - - mPicture.endRecording(); - } - ---------------------------------------------------------------- - - // 3.在使用前调用(我在构造函数中调用了) - public Canvas3(Context context, AttributeSet attrs) { - super(context, attrs); - - recording(); // 调用录制 - } - -``` - -**具体使用:** - -Picture虽然方法就那么几个,但是具体使用起来还是分很多情况的,由于录制的内容不会直接显示,就像存储的视频不点击播放不会自动播放一样,同样,想要将Picture中的内容显示出来就需要手动调用播放(绘制),将Picture中的内容绘制出来可以有以下几种方法: - -序号 | 简介 ------|----------- - 1 | 使用Picture提供的draw方法绘制。 - 2 | 使用Canvas提供的drawPicture方法绘制。 - 3 | 将Picture包装成为PictureDrawable,使用PictureDrawable的draw方法绘制。 - - -以上几种方法主要区别: - -主要区别 | 分类 | 简介 --------------------|-----------------------------------|------------------ -是否对Canvas有影响 | 1有影响
2,3不影响 | 此处指绘制完成后是否会影响Canvas的状态(Matrix clip等) -可操作性强弱 | 1可操作性较弱
2,3可操作性较强 | 此处的可操作性可以简单理解为对绘制结果可控程度。 - -几种方法简介和主要区别基本就这么多了,接下来对于各种使用方法一一详细介绍: - -**1.使用Picture提供的draw方法绘制:** -``` java - // 将Picture中的内容绘制在Canvas上 - mPicture.draw(canvas); -``` - - - -**PS:这种方法在比较低版本的系统上绘制后可能会影响Canvas状态,所以这种方法一般不会使用。** - -**2.使用Canvas提供的drawPicture方法绘制** - -drawPicture有三种方法: -``` java -public void drawPicture (Picture picture) - -public void drawPicture (Picture picture, Rect dst) - -public void drawPicture (Picture picture, RectF dst) -``` -和使用Picture的draw方法不同,Canvas的drawPicture不会影响Canvas状态。 - -**简单示例:** -``` java - canvas.drawPicture(mPicture,new RectF(0,0,mPicture.getWidth(),200)); -``` - - - - **PS:对照上一张图片,可以比较明显的看出,绘制的内容根据选区进行了缩放。 ** - -**3.将Picture包装成为PictureDrawable,使用PictureDrawable的draw方法绘制。** -``` - // 包装成为Drawable - PictureDrawable drawable = new PictureDrawable(mPicture); - // 设置绘制区域 -- 注意此处所绘制的实际内容不会缩放 - drawable.setBounds(0,0,250,mPicture.getHeight()); - // 绘制 - drawable.draw(canvas); -``` - - - -**PS:此处setBounds是设置在画布上的绘制区域,并非根据该区域进行缩放,也不是剪裁Picture,每次都从Picture的左上角开始绘制。** - -> **注意:在使用Picture之前请关闭硬件加速,以免引起不必要的问题,如何关闭请参考这里: [Android的硬件加速及可能导致的问题](https://github.com/GcsSloop/AndroidNote/issues/7)** - -### (2)drawBitmap - - > 其实一开始知道要讲Bitmap我是拒绝的,为什么呢?因为Bitmap就是很多问题的根源啊有木有,Bitmap可能导致内存不足,内存泄露,ListView中的复用混乱等诸多问题。想完美的掌控Bitmap还真不是一件容易的事情。限于篇幅**本文对于Bitmap不会过多的展开,只讲解一些常用的功能**,关于Bitmap详细内容,以后开专题讲解QAQ。 - - 既然要绘制Bitmap,就要先获取一个Bitmap,那么如何获取呢? - - **获取Bitmap方式:** - - 序号 | 获取方式 | 备注 - -----|---------------------------|----------------------------------------- - 1 | 通过Bitmap创建 | 复制一个已有的Bitmap(_新Bitmap状态和原有的一致_) 或者 创建一个空白的Bitmap(_内容可改变_) - 2 | 通过BitmapDrawable获取 | 从资源文件 内存卡 网络等地方获取一张图片并转换为内容不可变的Bitmap - 3 | 通过BitmapFactory获取 | 从资源文件 内存卡 网络等地方获取一张图片并转换为内容不可变的Bitmap - -**通常来说,我们绘制Bitmap都是读取已有的图片转换为Bitmap绘制到Canvas上。**
-很明显,第1种方式不能满足我们的要求,暂时排除。
-第2种方式虽然也可满足我们的要求,但是我不推荐使用这种方式,至于为什么在后续详细讲解Drawable的时候会说明,暂时排除。
-第3种方法我们会比较详细的说明一下如何从各个位置获取图片。
- -#### 通过BitmapFactory从不同位置获取Bitmap: - -**资源文件(drawable/mipmap/raw):** -``` java - Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(),R.raw.bitmap); -``` -**资源文件(assets):** -``` java - Bitmap bitmap=null; - try { - InputStream is = mContext.getAssets().open("bitmap.png"); - bitmap = BitmapFactory.decodeStream(is); - is.close(); - } catch (IOException e) { - e.printStackTrace(); - } -``` - -**内存卡文件:** -``` java - Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/bitmap.png"); -``` - -**网络文件:** -``` java - // 此处省略了获取网络输入流的代码 - Bitmap bitmap = BitmapFactory.decodeStream(is); - is.close(); -``` - -既然已经获得到了Bitmap,那么就开始本文的重点了,将Bitmap绘制到画布上。 - -#### 绘制Bitmap: - -依照惯例先预览一下drawBitmap的常用方法: -``` java - // 第一种 - public void drawBitmap (Bitmap bitmap, Matrix matrix, Paint paint) - - // 第二种 - public void drawBitmap (Bitmap bitmap, float left, float top, Paint paint) - - // 第三种 - public void drawBitmap (Bitmap bitmap, Rect src, Rect dst, Paint paint) - public void drawBitmap (Bitmap bitmap, Rect src, RectF dst, Paint paint) -``` - -第一种方法中后两个参数(matrix, paint)是在绘制的时候对图片进行一些改变,如果只是需要将图片内容绘制出来只需要如下操作就可以了: - -PS:图片左上角位置默认为坐标原点。 - -``` java - canvas.drawBitmap(bitmap,new Matrix(),new Paint()); -``` - -> 关于Matrix和Paint暂时略过吧,一展开又是啰啰嗦嗦一大段,反正挖坑已经是常态了,大家应该也习惯了(PAP). - - - -第二种方法就是在绘制时指定了图片左上角的坐标(距离坐标原点的距离): - -> **注意:此处指定的是与坐标原点的距离,并非是与屏幕顶部和左侧的距离, 虽然默认状态下两者是重合的,但是也请注意分别两者的不同。** - -``` java - canvas.drawBitmap(bitmap,200,500,new Paint()); -``` - - - -第三种方法比较有意思,上面多了两个矩形区域(src,dst),这两个矩形选区是干什么用的? - -名称 | 作用 ---------------------------|--------------------- -Rect src | 指定绘制图片的区域 -Rect dst 或RectF dst | 指定图片在屏幕上显示(绘制)的区域 - -示例: -``` java - // 将画布坐标系移动到画布中央 - canvas.translate(mWidth/2,mHeight/2); - - // 指定图片绘制区域(左上角的四分之一) - Rect src = new Rect(0,0,bitmap.getWidth()/2,bitmap.getHeight()/2); - - // 指定图片在屏幕上显示的区域 - Rect dst = new Rect(0,0,200,400); - - // 绘制图片 - canvas.drawBitmap(bitmap,src,dst,null); -``` - - -**详解:** - -上面是以绘制该图为例,用src指定了图片绘制部分的区域,即下图中红色方框标注的区域。 - -![](http://ww1.sinaimg.cn/large/005Xtdi2jw1f2kx2daw1qj305k05kq39.jpg) - -然后用dst指定了绘制在屏幕上的绘制,即下图中蓝色方框标注的区域,图片宽高会根据指定的区域自动进行缩放。 - - - -从上面可知,第三种方法可以绘制图片的一部分到画布上,这有什么用呢? - -如果你看过某些游戏的资源文件,你可能会看到如下的图片(图片来自网络): - -![](http://ww4.sinaimg.cn/large/005Xtdi2jw1f2kx3lk1ucj30kg04omz7.jpg) - -用一张图片包含了大量的素材,在绘制的时候每次只截取一部分进行绘制,这样可以大大的减少素材数量,而且素材管理起来也很方便。 - -然而这和我们有什么关系呢?我们又不做游戏开发。 - -确实,我们不做游戏开发,但是在某些时候我们需要制作一些炫酷的效果,这些效果因为太复杂了用代码很难实现或者渲染效率不高。这时候很多人就会想起帧动画,将动画分解成一张一张的图片然后使用帧动画制作出来,这种实现方式的确比较简单,但是一个动画效果的图片有十几到几十张,一个应用里面来几个这样炫酷的动画效果就会导致资源文件出现一大堆,想找其中的某一张资源图片简直就是灾难啊有木有。但是把同一个动画效果的所有资源图片整理到一张图片上,会大大的**减少资源文件数量,方便管理**,妈妈再也不怕我找不到资源文件了,**同时也节省了图片文件头、文件结束块以及调色板等占用的空间。** - -**下面是利用drawBitmap第三种方法制作的一个简单示例:** - -资源文件如下: - -![](https://raw.githubusercontent.com/GcsSloop/AndroidNote/master/CustomView/Advance/Res/Checkmark.png) - -最终效果如下: - -![](http://ww1.sinaimg.cn/large/005Xtdi2jw1f2kx67fkkog306g0b43yn.gif) - -源码如下: - -> PS:由于是示例代码,做的很粗糙,仅作为学习示例,不建议在任何实际项目中使用。 - -[_点击此处查看源码_](https://github.com/GcsSloop/AndroidNote/issues/10) - -## 2.绘制文字 -依旧预览一下相关常用方法: -``` java - // 第一类 - public void drawText (String text, float x, float y, Paint paint) - public void drawText (String text, int start, int end, float x, float y, Paint paint) - public void drawText (CharSequence text, int start, int end, float x, float y, Paint paint) - public void drawText (char[] text, int index, int count, float x, float y, Paint paint) - - // 第二类 - public void drawPosText (String text, float[] pos, Paint paint) - public void drawPosText (char[] text, int index, int count, float[] pos, Paint paint) - - // 第三类 - public void drawTextOnPath (String text, Path path, float hOffset, float vOffset, Paint paint) - public void drawTextOnPath (char[] text, int index, int count, Path path, float hOffset, float vOffset, Paint paint) -``` -> PS 其中的CharSequence和String的区别可以到这里看看. [->戳这里<-](https://github.com/GcsSloop/AndroidNote/issues/16) - -绘制文字部分大致可以分为三类: - -第一类只能指定文本基线位置位置(基线x默认在字符串左侧,基线y默认在字符串下方)。
-第二类可以分别指定每个文字的位置。
-第三类是指定一个路径,根据路径绘制文字。
- -通过上面常用方法的参数也可看出,绘制文字也是需要画笔的,而且文字的大小,颜色,字体,对齐方式都是由画笔控制的。 - -不过嘛这里仅简单介绍几种常用方法(反正挖坑多了也不怕),具体在讲解Paint时再详细讲解。 - -**Paint文本相关常用方法表** - -标题 | 相关方法 | 备注 ------|---------------------------|---------------------- -色彩 | setColor setARGB setAlpha | 设置颜色,透明度 -大小 | setTextSize | 设置文本字体大小 -字体 | setTypeface | 设置或清除字体样式 -样式 | setStyle | 填充(FILL),描边(STROKE),填充加描边(FILL_AND_STROKE) -对齐 | setTextAlign | 左对齐(LEFT),居中对齐(CENTER),右对齐(RIGHT) -测量 | measureText | 测量文本大小(注意,请在设置完文本各项参数后调用) - -为了绘制文本,我们先创建一个文本画笔: -``` java - Paint textPaint = new Paint(); // 创建画笔 - textPaint.setColor(Color.BLACK); // 设置颜色 - textPaint.setStyle(Paint.Style.FILL); // 设置样式 - textPaint.setTextSize(50); // 设置字体大小 -``` - -### 第一类(drawText) -第一类可以指定文本开始的位置,可以截取文本中部分内容进行绘制。 - -其中x,y两个参数是指定文本绘制两个基线,示例: -``` java - - // 文本(要绘制的内容) - String str = "ABCDEFGHIJK"; - - // 参数分别为 (文本 基线x 基线y 画笔) - canvas.drawText(str,200,500,textPaint); -``` - - -> PS: 图中字符串下方的红线是基线y,基线x未在图中画出。 - -当然啦,除了能指定绘制文本的起始位置,还能只取出文本中的一部分内容进行绘制。 - -截取文本中的一部分,对于String和CharSequence来说只指定字符串下标start和end位置(**注意:0<= start < end < str.length()**) - -以上一个例子使用的字符串为例,它的下标是这样的(wait,我为啥要说这个,算了,不管了,就这样吧(๑•́ ₃ •̀๑)): - -字符 | A | B | C | D | E | F | G | H | I | J | K - ---|---|---|---|---|---|---|---|---|---|---|--- -下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 - -假设我我们指定star为1,end为3,那么最终截取的字符串就是"BC"。 - -一般来说,**使用start和end指定的区间是前闭后开的,即包含start指定的下标,而不包含end指定的下标**,故[1,3)最后获取到的下标只有 下标1 和 下标2 的字符,就是"BC". - -示例: -``` java - // 文本(要绘制的内容) - String str = "ABCDEFGHIJK"; - // 参数分别为 (字符串 开始截取位置 结束截取位置 基线x 基线y 画笔) - canvas.drawText(str,1,3,200,500,textPaint); -``` - - -另外,对于字符数组char[]我们截取字符串使用起始位置(index)和长度(count)来确定。 - -同样,我们指定index为1,count为3,那么最终截取到的字符串是"BCD". - -其实就是从下标位置为1处向后数3位就是截取到的字符串,示例: -``` java - // 字符数组(要绘制的内容) - char[] chars = "ABCDEFGHIJK".toCharArray(); - - // 参数为 (字符数组 起始坐标 截取长度 基线x 基线y 画笔) - canvas.drawText(chars,1,3,200,500,textPaint); -``` - - -### 第二类(drawPosText) - -通过和第一类比较,我们可以发现,第二类中没有指定x,y坐标的参数,而是出现了这样一个参数**float[] pos**。 - -好吧,这个名为pos的浮点型数组就是指定坐标的,至于为啥要用数组嘛,因为这家伙野心比较大,想给每个字符都指定一个位置。 - -示例: -``` java - String str = "SLOOP"; - - canvas.drawPosText(str,new float[]{ - 100,100, // 第一个字符位置 - 200,200, // 第二个字符位置 - 300,300, // ... - 400,400, - 500,500 - },textPaint); -``` - - - -不过嘛,虽然虽然这个方法也比较容易理解,但是关于这个方法我个人是不推荐使用的,因为坑比较的,主要有一下几点: - -序号 | 反对理由 ------|---------------------- - 1 | 必须指定所有字符位置,否则直接crash掉,反人类设计 - 2 | 性能不佳,在大量使用的时候可能导致卡顿 - 3 | 不支持emoji等特殊字符,不支持字形组合与分解 - -关于第二类的第二种方法: - -``` java -public void drawPosText (char[] text, int index, int count, float[] pos, Paint paint) -``` - -和上面一样,就是从字符数组中切出来一段进行绘制,相信以诸位看官的聪明才智一眼就看出来了,我这里就不多说了,真的不是我偷懒啊(ˉ▽ ̄~) ~~ - -### 第三类(drawTextOnPath) - -第三类要用到path这个大杀器,作为一个厉害角色怎么能这么轻易露脸呢,先保持一下神秘感,也就是说,下回再和大家见面喽。 - -# 三.总结 - -学会了图片和文字绘制,对于大部分自定义View都能制作了,可以去看看这位大神制作的作品,尝试模仿一下[一个绚丽的loading动效分析与实现!](http://blog.csdn.net/tianjian4592/article/details/44538605) - -![](http://ww4.sinaimg.cn/large/005Xtdi2jw1f2kxbki0wtg308c069mzr.gif) - -(,,• ₃ •,,) - -PS: 由于本人英文水平有限,某些地方可能存在误解或词语翻译不准确,如果你对此有疑问可以提交Issues进行反馈。 - -## About Me - -### 作者微博: @GcsSloop - - - -## 参考资料 - -[Canvas](http://developer.android.com/reference/android/graphics/Canvas.html)
-[Bitmap](http://developer.android.com/reference/android/graphics/Bitmap.html)
-[Paint](http://developer.android.com/reference/android/graphics/Paint.html)
-[Android ApiDemo 笔记(一)Content与Graphics](http://blog.csdn.net/wufenglong/article/details/5596402)
- diff --git a/CustomView/Advance/[5]Path_Basic.md b/CustomView/Advance/[5]Path_Basic.md deleted file mode 100644 index acd7df0c..00000000 --- a/CustomView/Advance/[5]Path_Basic.md +++ /dev/null @@ -1,581 +0,0 @@ -# Path之基本操作 - -### 作者微博: [@GcsSloop](http://weibo.com/GcsSloop) - -### [【本系列相关文章】](https://github.com/GcsSloop/AndroidNote/tree/master/CustomView) - -在上一篇[Canvas之图片文字](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B4%5DCanvas_PictureText.md)中我们了解了如何使用Canvas中绘制图片文字,结合前几篇文章,Canvas的基本操作已经差不多完结了,然而Canvas不仅仅具有这些基本的操作,还可以更加炫酷,本次会了解到path(路径)这个Canvas中的神器,有了这个神器,就能创造出更多**炫(zhuang)酷(B)**的东东了。 - -****** - -# 一.Path常用方法表 -> 为了兼容性(_偷懒_) 本表格中去除了部分API21(即安卓版本5.0)以上才添加的方法。 - -作用 | 相关方法 | 备注 -----------------|-----------------|------------------------------------------ -移动起点 | moveTo | 移动下一次操作的起点位置 -设置终点 | setLastPoint | 重置当前path中最后一个点位置,如果在绘制之前调用,效果和moveTo相同 -连接直线 | lineTo | 添加上一个点到当前点之间的直线到Path -闭合路径 | close | 连接第一个点连接到最后一个点,形成一个闭合区域 -添加内容 | addRect, addRoundRect, addOval, addCircle, addPath, addArc, arcTo | 添加(矩形, 圆角矩形, 椭圆, 圆, 路径, 圆弧) 到当前Path (注意addArc和arcTo的区别) -是否为空 | isEmpty | 判断Path是否为空 -是否为矩形 | isRect | 判断path是否是一个矩形 -替换路径 | set | 用新的路径替换到当前路径所有内容 -偏移路径 | offset | 对当前路径之前的操作进行偏移(不会影响之后的操作) -贝塞尔曲线 | quadTo, cubicTo | 分别为二次和三次贝塞尔曲线的方法 -rXxx方法 | rMoveTo, rLineTo, rQuadTo, rCubicTo | **不带r的方法是基于原点的坐标系(偏移量), rXxx方法是基于当前点坐标系(偏移量)** -填充模式 | setFillType, getFillType, isInverseFillType, toggleInverseFillType | 设置,获取,判断和切换填充模式 -提示方法 | incReserve | 提示Path还有多少个点等待加入**(这个方法貌似会让Path优化存储结构)** -布尔操作(API19) | op | 对两个Path进行布尔运算(即取交集、并集等操作) -计算边界 | computeBounds | 计算Path的边界 -重置路径 | reset, rewind | 清除Path中的内容
**reset不保留内部数据结构,但会保留FillType.**
**rewind会保留内部的数据结构,但不保留FillType** -矩阵操作 | transform | 矩阵变换 - - -# 二.Path详解 - -**请关闭硬件加速,以免引起不必要的问题!
请关闭硬件加速,以免引起不必要的问题!
请关闭硬件加速,以免引起不必要的问题!** - -**在AndroidMenifest文件中application节点下添上 android:hardwareAccelerated="false"以关闭整个应用的硬件加速。
更多请参考这里:[Android的硬件加速及可能导致的问题](https://github.com/GcsSloop/AndroidNote/issues/7)** - -## Path作用 -本次特地开了一篇详细讲解Path,为什么要单独摘出来呢,这是因为Path在2D绘图中是一个很重要的东西。 - -在前面我们讲解的所有绘制都是简单图形(如 矩形 圆 圆弧等),而对于那些复杂一点的图形则没法去绘制(如绘制一个心形 正多边形 五角星等),而**使用Path不仅能够绘制简单图形,也可以绘制这些比较复杂的图形。另外,根据路径绘制文本和剪裁画布都会用到Path。** - -关于Path的作用先简单地说这么多,具体的我们接下来慢慢研究。 - -## Path含义 - -**官方介绍:** - -_The Path class encapsulates compound (multiple contour) geometric paths consisting of straight line segments, quadratic curves, and cubic curves. It can be drawn with canvas.drawPath(path, paint), either filled or stroked (based on the paint's Style), or it can be used for clipping or to draw text on a path._ - -> 嗯,没错依旧是拿来装逼的,如果你看不懂的话,不用担心,其实并没有什么卵用。 - -**通俗解释(sloop个人版):** - -**Path是封装了由直线和曲线(二次,三次贝塞尔曲线)构成的几何路径。你能用Canvas中的drawPath来把这条路径画出来(同样支持Paint的不同绘制模式),也可以用于剪裁画布和根据路径绘制文字。我们有时会用Path来描述一个图像的轮廓,所以也会称为轮廓线(轮廓线仅是Path的一种使用方法,两者并不等价)** - - -另外路径有开放和封闭的区别。 - -图像 | 名称 | 备注 - --- | --- | --- - ![](http://ww4.sinaimg.cn/thumbnail/005Xtdi2jw1f0zx9g9gggj30f00aiwek.jpg) | 封闭路径 | 首尾相接形成了一个封闭区域 - ![](http://ww1.sinaimg.cn/thumbnail/005Xtdi2jw1f0zxg8ilpxj30f00aimx8.jpg) | 开放路径 | 没有首位相接形成封闭区域 - -> 这个是我随便画的,仅为展示一下区别,请无视我灵魂画师一般的绘图水准。 - -**与Path相关的还有一些比较神奇的概念,不过暂且不说,等接下来需要用到的时候再详细说明。** - -## Path使用方法详解 - -前面扯了一大堆概念性的东西。接下来就开始实战了,请诸位看官准备好瓜子、花生、爆米花,坐下来慢慢观看。 - -![](http://ww3.sinaimg.cn/large/005Xtdi2jw1f19mncfcirj305i02j744.jpg) - -### 第1组: moveTo、 setLastPoint、 lineTo 和 close - -由于Path的有些知识点无法单独来讲,所以本次采取了一次讲一组方法。 - -按照惯例,先创建画笔: - -``` java - Paint mPaint = new Paint(); // 创建画笔 - mPaint.setColor(Color.BLACK); // 画笔颜色 - 黑色 - mPaint.setStyle(Paint.Style.STROKE); // 填充模式 - 描边 - mPaint.setStrokeWidth(10); // 边框宽度 - 10 -``` - -#### lineTo: -方法预览: -``` -public void lineTo (float x, float y) -``` - - 首先讲解的的LineTo,为啥先讲解这个呢? - - 是因为moveTo、 setLastPoint、 close都无法直接看到效果,借助有具现化效果的lineTo才能让这些方法现出原形。 - - - -lineTo很简单,只有一个方法,作用也很容易理解,line嘛,顾名思义就是一条线。 - -俗话(数学书上)说,两点确定一条直线,但是看参数明显只给了一个点的坐标吧(这不按常理出牌啊)。 - -再仔细一看,这个lineTo除了line外还有一个to呢,to翻译过来就是“至”,到某个地方的意思,**lineTo难道是指从某个点到参数坐标点之间连一条线?** - -没错,你猜对了,但是这某个点又是哪里呢? - -前面我们提到过Path可以用来描述一个图像的轮廓,图像的轮廓通常都是用一条线构成的,所以这里的某个点就是上次操作结束的点,如果没有进行过操作则默认点为坐标原点。 - -那么我们就来试一下: - -``` java - canvas.translate(mWidth / 2, mHeight / 2); // 移动坐标系到屏幕中心(宽高数据在onSizeChanged中获取) - - Path path = new Path(); // 创建Path - - path.lineTo(200, 200); // lineTo - path.lineTo(200,0); - - canvas.drawPath(path, mPaint); // 绘制Path -``` - - - - -在示例中我们调用了两次lineTo,**第一次由于之前没有过操作,所以默认点就是坐标原点O,结果就是坐标原点O到A(200,200)之间连直线(用蓝色圈1标注)。** - -**第二次lineTo的时候,由于上次的结束位置是A(200,200),所以就是A(200,200)到B(200,0)之间的连线(用蓝色圈2标注)。** - -#### moveTo 和 setLastPoint: - -方法预览: -``` java - // moveTo - public void moveTo (float x, float y) - - // setLastPoint - public void setLastPoint (float dx, float dy) -``` - -这两个方法虽然在作用上有相似之处,但实际上却是完全不同的两个东东,具体参照下表: - -方法名 | 简介 | 是否影响之前的操作 | 是否影响之后操作 ---- | --- | --- | --- -moveTo | 移动下一次操作的起点位置 | 否 | 是 -setLastPoint | 设置之前操作的最后一个点位置 | 是 | 是 - -废话不多说,直接上代码: -``` java - canvas.translate(mWidth / 2, mHeight / 2); // 移动坐标系到屏幕中心 - - Path path = new Path(); // 创建Path - - path.lineTo(200, 200); // lineTo - - path.moveTo(200,100); // moveTo - - path.lineTo(200,0); // lineTo - - canvas.drawPath(path, mPaint); // 绘制Path -``` - - -这个和上面演示lineTo的方法类似,只不过在两个lineTo之间添加了一个moveTo。 - -**moveTo只改变下次操作的起点,在执行完第一次LineTo的时候,本来的默认点位置是A(200,200),但是moveTo将其改变成为了C(200,100),所以在第二次调用lineTo的时候就是连接C(200,100) 到 B(200,0) 之间的直线(用蓝色圈2标注)。** - -下面是setLastPoint的示例: - -``` java - canvas.translate(mWidth / 2, mHeight / 2); // 移动坐标系到屏幕中心 - - Path path = new Path(); // 创建Path - - path.lineTo(200, 200); // lineTo - - path.setLastPoint(200,100); // setLastPoint - - path.lineTo(200,0); // lineTo - - canvas.drawPath(path, mPaint); // 绘制Path -``` - - -**setLastPoint是重置上一次操作的最后一个点,在执行完第一次的lineTo的时候,最后一个点是A(200,200),而setLastPoint更改最后一个点为C(200,100),所以在实际执行的时候,第一次的lineTo就不是从原点O到A(200,200)的连线了,而变成了从原点O到C(200,100)之间的连线了。** - -**在执行完第一次lineTo和setLastPoint后,最后一个点的位置是C(200,100),所以在第二次调用lineTo的时候就是C(200,100) 到 B(200,0) 之间的连线(用蓝色圈2标注)。** - -#### close - -方法预览: -``` java - public void close () -``` - -close方法用于连接当前最后一个点和最初的一个点(如果两个点不重合的话),最终形成一个封闭的图形。 - -``` java - canvas.translate(mWidth / 2, mHeight / 2); // 移动坐标系到屏幕中心 - - Path path = new Path(); // 创建Path - - path.lineTo(200, 200); // lineTo - - path.lineTo(200,0); // lineTo - - path.close(); // close - - canvas.drawPath(path, mPaint); // 绘制Path -``` - - -很明显,两个lineTo分别代表第1和第2条线,而close在此处的作用就算连接了B(200,0)点和圆的O之间的第3条线,使之形成一个封闭的图形。 - -**注意:close的作用是封闭路径,与当前最后一个点和第一个点并不等价。如果连接了最后一个点和第一个点仍然无法形成封闭图形,则close什么 也不做。** - -### 第2组: addXxx与arcTo - -这次内容主要是在Path中添加基本图形,重点区分addArc与arcTo。 - -#### 第一类(基本形状) -方法预览: -``` java -// 第一类(基本形状) - // 圆形 - public void addCircle (float x, float y, float radius, Path.Direction dir) - // 椭圆 - public void addOval (RectF oval, Path.Direction dir) - // 矩形 - public void addRect (float left, float top, float right, float bottom, Path.Direction dir) - public void addRect (RectF rect, Path.Direction dir) - // 圆角矩形 - public void addRoundRect (RectF rect, float[] radii, Path.Direction dir) - public void addRoundRect (RectF rect, float rx, float ry, Path.Direction dir) -``` - -**这一类就是在path中添加一个基本形状,基本形状部分和前面所讲的绘制基本形状并无太大差别,详情参考[Canvas(1)颜色与基本形状](https://github.com/GcsSloop/AndroidNote/blob/master/%E9%97%AE%E9%A2%98/Canvas/Canvas(1).md), 本次只将其中不同的部分摘出来详细讲解一下。** - -**仔细观察一下第一类是方法,无一例外,在最后都有一个_Path.Direction_,这是一个什么神奇的东东?** - -Direction的意思是 方向,趋势。 点进去看一下会发现Direction是一个枚举(Enum)类型,里面只有两个枚举常量,如下: - -类型 | 解释 | 翻译 ------|-------------------|------- -CW | clockwise | 顺时针 -CCW | counter-clockwise | 逆时针 - -> **瞬间懵逼,我只是想添加一个基本的形状啊,搞什么顺时针和逆时针, (╯‵□′)╯︵┻━┻** - -**稍安勿躁,┬─┬ ノ( ' - 'ノ) {摆好摆好) 既然存在肯定是有用的,先偷偷剧透一下这个顺时针和逆时针的作用。** - -序号 | 作用 ------|--------------------------------------------------- - 1 | 在添加图形时确定闭合顺序(各个点的记录顺序) - 2 | 对图形的渲染结果有影响(是判断图形渲染的重要条件) - -这个先剧透这么多,至于对闭合顺序有啥影响,自相交图形的渲染等问题等请慢慢看下去 - -咱们先研究确定闭合顺序的问题,添加一个矩形试试看: - -``` java - canvas.translate(mWidth / 2, mHeight / 2); // 移动坐标系到屏幕中心 - - Path path = new Path(); - - path.addRect(-200,-200,200,200, Path.Direction.CW); - - canvas.drawPath(path,mPaint); -``` - - -**将上面代码的CW改为CCW再运行一次。接下来就是见证奇迹的时刻,两次运行结果一模一样,有木有很神奇!** - -> **(╯°Д°)╯︵ ┻━┻(再TM掀一次) -坑人也不带这样的啊,一毛一样要它干嘛。** - -**其实啊,这个东东是自带隐身技能的,想要让它现出原形,就要用到咱们刚刚学到的setLastPoint(重置当前最后一个点的位置)。** - -``` - canvas.translate(mWidth / 2, mHeight / 2); // 移动坐标系到屏幕中心 - - Path path = new Path(); - - path.addRect(-200,-200,200,200, Path.Direction.CW); - - path.setLastPoint(-300,300); // <-- 重置最后一个点的位置 - - canvas.drawPath(path,mPaint); -``` - - - -可以明显看到,图形发生了奇怪的变化。为何会如此呢? - -我们先分析一下,绘制一个矩形(仅绘制边线),实际上只需要进行四次lineTo操作就行了,也就是说,只需要知道4个点的坐标,然后使用moveTo到第一个点,之后依次lineTo就行了(从上面的测试可以看出,在实际绘制中也确实是这么干的)。 - -可是为什么要这么做呢?确定一个矩形最少需要两个点(对角线的两个点),根据这两个点的坐标直接算出四条边然后画出来不就行了,干嘛还要先计算出四个点坐标,之后再连直线呢? - -这个就要涉及一些path的存储问题了,前面在path中的定义中说过,Path是封装了由直线和曲线(二次,三次贝塞尔曲线)构成的几何路径。其中曲线部分用的是贝塞尔曲线,稍后再讲。 然而除了曲线部分就只剩下直线了,对于直线的存储最简单的就是记录坐标点,然后直接连接各个点就行了。虽然记录矩形只需要两个点,但是如果只用两个点来记录一个矩形的话,就要额外增加一个标志位来记录这是一个矩形,显然对于存储和解析都是很不划算的事情,将矩形转换为直线,为的就是存储记录方便。 - -**扯了这么多,该回归正题了,就是我们的顺时针和逆时针在这里是干啥的?** - -图形在实际记录中就是记录各个的点,对于一个图形来说肯定有多个点,既然有这么多的点,肯定就需要一个先后顺序,这里顺时针和逆时针就是用来确定记录这些点的顺序的。 - -对于上面这个矩形来说,我们采用的是顺时针(CW),所以记录的点的顺序就是 A -> B -> C -> D. 最后一个点就是D,我们这里使用setLastPoint改变最后一个点的位置实际上是改变了D的位置。 - -理解了上面的原理之后,设想如果我们将顺时针改为逆时针(CCW),则记录点的顺序应该就是 A -> D -> C -> B, 再使用setLastPoint则改变的是B的位置,我们试试看结果和我们的猜想是否一致: - -``` java - canvas.translate(mWidth / 2, mHeight / 2); // 移动坐标系到屏幕中心 - - Path path = new Path(); - - path.addRect(-200,-200,200,200, Path.Direction.CCW); - - path.setLastPoint(-300,300); // <-- 重置最后一个点的位置 - - canvas.drawPath(path,mPaint); -``` - - - -通过验证发现,发现结果和我们猜想的一样,但是还有一个潜藏的问题不晓得大家可否注意到。**我们用两个点的坐标确定了一个矩形,矩形起始点(A)就是我们指定的第一个点的坐标。** - -**需要注意的是,交换坐标点的顺序可能就会影响到某些绘制内容哦,例如上面的例子,你可以尝试交换两个坐标点,或者指定另外两个点来作为参数,虽然指定的是同一个矩形,但实际绘制出来是不同的哦。** - -**参数中点的顺序很重要!
参数中点的顺序很重要!
参数中点的顺序很重要!
** - -重要的话说三遍,本次是用矩形作为例子的,其他的几个图形基本上都包含了曲线,详情参见后续的贝塞尔曲线部分。 - -**关于顺时针和逆时针对图形填充结果的影响请等待后续文章,虽然只讲了一个Path,但也是内容颇多,放进一篇中就太长了,请见谅。** - -#### 第二类(Path) -方法预览: -``` java -// 第二类(Path) - // path - public void addPath (Path src) - public void addPath (Path src, float dx, float dy) - public void addPath (Path src, Matrix matrix) -``` - - -这个相对比较简单,也很容易理解,就是将两个Path合并成为一个。 - -第三个方法是将src添加到当前path之前先使用Matrix进行变换。 - -第二个方法比第一个方法多出来的两个参数是将src进行了位移之后再添加进当前path中。 - -示例: -``` java - canvas.translate(mWidth / 2, mHeight / 2); // 移动坐标系到屏幕中心 - canvas.scale(1,-1); // <-- 注意 翻转y坐标轴 - - Path path = new Path(); - Path src = new Path(); - - path.addRect(-200,-200,200,200, Path.Direction.CW); - src.addCircle(0,0,100, Path.Direction.CW); - - path.addPath(src,0,200); - - mPaint.setColor(Color.BLACK); // 绘制合并后的路径 - canvas.drawPath(path,mPaint); -``` - - - -首先我们新建地方两个Path(矩形和圆形)中心都是坐标原点,我们在将包含圆形的path添加到包含矩形的path之前将其进行移动了一段距离,最终绘制出来的效果就如上面所示。 - -#### 第三类(addArc与arcTo) -方法预览: -``` java -// 第三类(addArc与arcTo) - // addArc - public void addArc (RectF oval, float startAngle, float sweepAngle) - // arcTo - public void arcTo (RectF oval, float startAngle, float sweepAngle) - public void arcTo (RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo) -``` - -从名字就可以看出,这两个方法都是与圆弧相关的,作用都是添加一个圆弧到path中,但既然存在两个方法,两者之间肯定是有区别的: - -名称 | 作用 | 区别 - --- | --- | --- - addArc | 添加一个圆弧到path | 直接添加一个圆弧到path中 - arcTo | 添加一个圆弧到path | 添加一个圆弧到path,如果圆弧的起点和上次最后一个坐标点不相同,就连接两个点 - -可以看到addArc有1个方法(_实际上是两个的,但另一个重载方法是API21添加的_), 而arcTo有2个方法,其中一个最后多了一个布尔类型的变量forceMoveTo。 - -**forceMoveTo是什么作用呢?** - -这个变量意思为“是否强制使用moveTo”,也就是说,是否使用moveTo将变量移动到圆弧的起点位移,也就意味着: - -forceMoveTo | 含义 | 等价方法 - --- | --- | --- - true | 将最后一个点移动到圆弧起点,即不连接最后一个点与圆弧起点 | public void addArc (RectF oval, float startAngle, float sweepAngle) - false | 不移动,而是连接最后一个点与圆弧起点 | public void arcTo (RectF oval, float startAngle, float sweepAngle) - -**示例(addArc):** -``` java - canvas.translate(mWidth / 2, mHeight / 2); // 移动坐标系到屏幕中心 - canvas.scale(1,-1); // <-- 注意 翻转y坐标轴 - - Path path = new Path(); - path.lineTo(100,100); - - RectF oval = new RectF(0,0,300,300); - - path.addArc(oval,0,270); - // path.arcTo(oval,0,270,true); // <-- 和上面一句作用等价 - - canvas.drawPath(path,mPaint); -``` - - - -**示例(arcTo):** -``` java - canvas.translate(mWidth / 2, mHeight / 2); // 移动坐标系到屏幕中心 - canvas.scale(1,-1); // <-- 注意 翻转y坐标轴 - - Path path = new Path(); - path.lineTo(100,100); - - RectF oval = new RectF(0,0,300,300); - - path.arcTo(oval,0,270); - // path.arcTo(oval,0,270,false); // <-- 和上面一句作用等价 - - canvas.drawPath(path,mPaint); -``` - - - -从上面两张运行效果图可以清晰的看出来两者的区别,我就不再废话了。 - -### 第3组:isEmpty、 isRect、isConvex、 set 和 offset - -这一组比较简单,稍微说一下就可以了。 - -#### isEmpty -方法预览: -``` java - public boolean isEmpty () -``` - -判断path中是否包含内容。 - -``` java - Path path = new Path(); - Log.e("1",path.isEmpty()+""); - - path.lineTo(100,100); - Log.e("2",path.isEmpty()+""); -``` - -log输出结果: - -``` -03-02 14:22:54.770 12379-12379/com.sloop.canvas E/1: true -03-02 14:22:54.770 12379-12379/com.sloop.canvas E/2: false -``` - -#### isRect -方法预览: -``` java -public boolean isRect (RectF rect) -``` - -判断path是否是一个矩形,如果是一个矩形的话,会将矩形的信息存放进参数rect中。 - -``` java - path.lineTo(0,400); - path.lineTo(400,400); - path.lineTo(400,0); - path.lineTo(0,0); - - RectF rect = new RectF(); - boolean b = path.isRect(rect); - Log.e("Rect","isRect:"+b+"| left:"+rect.left+"| top:"+rect.top+"| right:"+rect.right+"| bottom:"+rect.bottom); -``` - -log 输出结果: -``` -03-02 16:48:39.669 24179-24179/com.sloop.canvas E/Rect: isRect:true| left:0.0| top:0.0| right:400.0| bottom:400.0 -``` - -#### set -方法预览: -``` java - public void set (Path src) -``` - -将新的path赋值到现有path。 - -``` java - canvas.translate(mWidth / 2, mHeight / 2); // 移动坐标系到屏幕中心 - canvas.scale(1,-1); // <-- 注意 翻转y坐标轴 - - Path path = new Path(); // path添加一个矩形 - path.addRect(-200,-200,200,200, Path.Direction.CW); - - Path src = new Path(); // src添加一个圆 - src.addCircle(0,0,100, Path.Direction.CW); - - path.set(src); // 大致相当于 path = src; - - canvas.drawPath(path,mPaint); -``` - - -#### offset -方法预览: -```java - public void offset (float dx, float dy) - public void offset (float dx, float dy, Path dst) -``` - -这个的作用也很简单,就是对path进行一段平移,它和Canvas中的translate作用很像,但Canvas作用于整个画布,而path的offset只作用于当前path。 - -**但是第二个方法最后怎么会有一个path作为参数?** - -其实第二个方法中最后的参数das是存储平移后的path的。 - -dst状态 | 效果 - --------------|--------------------------------- - dst不为空 | 将当前path平移后的状态存入dst中,不会影响当前path - dat为空(null) | 平移将作用于当前path,相当于第一种方法 - -示例: -``` java - canvas.translate(mWidth / 2, mHeight / 2); // 移动坐标系到屏幕中心 - canvas.scale(1,-1); // <-- 注意 翻转y坐标轴 - - Path path = new Path(); // path中添加一个圆形(圆心在坐标原点) - path.addCircle(0,0,100, Path.Direction.CW); - - Path dst = new Path(); // dst中添加一个矩形 - dst.addRect(-200,-200,200,200, Path.Direction.CW); - - path.offset(300,0,dst); // 平移 - - canvas.drawPath(path,mPaint); // 绘制path - - mPaint.setColor(Color.BLUE); // 更改画笔颜色 - - canvas.drawPath(dst,mPaint); // 绘制dst -``` - - -从运行效果图可以看出,虽然我们在dst中添加了一个矩形,但是并没有表现出来,所以,当dst中存在内容时,dst中原有的内容会被清空,而存放平移后的path。 - -# 三.总结 - -本想一篇把path写完,但是万万没想到居然扯了这么多。本篇中讲解的是直线部分和一些常用方法,下一篇将着重讲解贝塞尔曲线和自相交图形渲染等相关问题,敬请期待哦。 - -学完本篇之后又解锁了新的境界,可以看看这位大神的文章[ Android雷达图(蜘蛛网图)绘制](http://blog.csdn.net/crazy__chen/article/details/50163693) - -![](http://img.blog.csdn.net/20151203171214218) - -这个精小干练,非常适合新手练习使用,帮助大家更好的熟悉path的使用。 - -(,,• ₃ •,,) - -PS: 由于本人水平有限,某些地方可能存在误解或不准确,如果你对此有疑问可以提交Issues进行反馈。 - -## About Me - -### 作者微博: @GcsSloop - - - -## 参考资料 - -[Path](http://developer.android.com/reference/android/graphics/Path.html)
-[Canvas](http://developer.android.com/reference/android/graphics/Canvas.html)
-[android绘图之Path总结](http://ghui.me/post/2015/10/android-graphics-path/)
diff --git a/CustomView/Advance/[6]Path_Bezier.md b/CustomView/Advance/[6]Path_Bezier.md deleted file mode 100644 index cade573c..00000000 --- a/CustomView/Advance/[6]Path_Bezier.md +++ /dev/null @@ -1,591 +0,0 @@ -# Path之贝塞尔曲线 - -### 作者微博: [@GcsSloop](http://weibo.com/GcsSloop) -### [【本系列相关文章】](https://github.com/GcsSloop/AndroidNote/tree/master/CustomView) - -在上一篇文章[Path之基本图形](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B5%5DPath_BasicGraphics.md)中我们了解了Path的基本使用方法,本次了解Path中非常非常非常重要的内容-贝塞尔曲线。 - - -****** - -## 一.Path常用方法表 -> 为了兼容性(_偷懒_) 本表格中去除了在API21(即安卓版本5.0)以上才添加的方法。忍不住吐槽一下,为啥看起来有些顺手就能写的重载方法要等到API21才添加上啊。宝宝此刻内心也是崩溃的。 - -作用 | 相关方法 | 备注 -----------------|-----------------|------------------------------------------ -移动起点 | moveTo | 移动下一次操作的起点位置 -设置终点 | setLastPoint | 重置当前path中最后一个点位置,如果在绘制之前调用,效果和moveTo相同 -连接直线 | lineTo | 添加上一个点到当前点之间的直线到Path -闭合路径 | close | 连接第一个点连接到最后一个点,形成一个闭合区域 -添加内容 | addRect, addRoundRect, addOval, addCircle, addPath, addArc, arcTo | 添加(矩形, 圆角矩形, 椭圆, 圆, 路径, 圆弧) 到当前Path (注意addArc和arcTo的区别) -是否为空 | isEmpty | 判断Path是否为空 -是否为矩形 | isRect | 判断path是否是一个矩形 -替换路径 | set | 用新的路径替换到当前路径所有内容 -偏移路径 | offset | 对当前路径之前的操作进行偏移(不会影响之后的操作) -贝塞尔曲线 | quadTo, cubicTo | 分别为二次和三次贝塞尔曲线的方法 -rXxx方法 | rMoveTo, rLineTo, rQuadTo, rCubicTo | **不带r的方法是基于原点的坐标系(偏移量), rXxx方法是基于当前点坐标系(偏移量)** -填充模式 | setFillType, getFillType, isInverseFillType, toggleInverseFillType | 设置,获取,判断和切换填充模式 -提示方法 | incReserve | 提示Path还有多少个点等待加入**(这个方法貌似会让Path优化存储结构)** -布尔操作(API19) | op | 对两个Path进行布尔运算(即取交集、并集等操作) -计算边界 | computeBounds | 计算Path的边界 -重置路径 | reset, rewind | 清除Path中的内容
**reset不保留内部数据结构,但会保留FillType.**
**rewind会保留内部的数据结构,但不保留FillType** -矩阵操作 | transform | 矩阵变换 - -## 二.Path详解 - -上一次除了一些常用函数之外,讲解的基本上都是直线,本次需要了解其中的曲线部分,说到曲线,就不得不提大名鼎鼎的贝塞尔曲线。它的发明者是下面这个人(法国数学家PierreBézier)。 - -![](http://ww4.sinaimg.cn/large/005Xtdi2jw1f1ky5bw28pg305k07h3yo.gif) - -### 贝塞尔曲线能干什么? - -贝塞尔曲线的运用是十分广泛的,可以说**贝塞尔曲线奠定了计算机绘图的基础(_因为它可以将任何复杂的图形用精确的数学语言进行描述_)**,在你不经意间就已经使用过它了。 - -你会使用Photoshop的话,你可能会注意到里面有一个**钢笔工具**,这个钢笔工具核心就是贝塞尔曲线。 - -你说你不会PS? 没关系,你如果看过前面的文章或者用过2D绘图,肯定绘制过圆,圆弧,圆角矩形等这些东西。这里面的圆弧部分全部都是贝塞尔曲线的运用。 - -#### 贝塞尔曲线作用十分广泛,简单举几个的栗子: -> * QQ小红点拖拽效果 -* 一些炫酷的下拉刷新控件 -* 阅读软件的翻书效果 -* 一些平滑的折线图的制作 -* 很多炫酷的动画效果 - - -### 如何轻松入门贝塞尔曲线? - -虽然贝塞尔曲线用途非常广泛,然而目前貌似并没有适合的中文教程,能够搜索出来Android关于贝塞尔曲线的中文文章基本可以分为以下几种: -* 科普型(只是让人了解贝塞尔,并没有实质性的内容) -* 装逼型(摆出来一大堆公式,引用一堆英文原文) -* 基础型(仅仅是讲解贝塞尔曲线的两个函数用法) -* 实战型(根据实例讲解其中贝塞尔曲线的运用) - -以上几种类型中比较有用的就是基础型和实战型,但两者各有不足,本文会综合两者内容,从零开始学习贝塞尔曲线。 - -### 第一步.理解贝塞尔曲线的原理 - -此处理解贝塞尔曲线并非是学会公式的推导过程(不是推倒(ノ*・ω・)ノ),而是要了解贝塞尔曲线是如何生成的。 -贝塞尔曲线是用一系列点来控制曲线状态的,我将这些点简单分为两类: - - 类型 | 作用 --------|------ -数据点 | 确定曲线的起始和结束位置 -控制点 | 确定曲线的弯曲程度 - -> 此处暂时仅作了解概念,接下来就会讲解其中详细的含义。 - -**一阶曲线原理:** - -一阶曲线是没有控制点的,仅有两个数据点(A 和 B),最终效果一个线段。 - -![](http://ww1.sinaimg.cn/large/005Xtdi2jw1f35of045w8j308c0dwq2z.jpg) - -> **上图表示的是一阶曲线生成过程中的某一个阶段,动态过程可以参照下图(本文中贝塞尔曲线相关的动态演示图片来自维基百科)。** - -![](https://upload.wikimedia.org/wikipedia/commons/0/00/B%C3%A9zier_1_big.gif) - -> **PS:一阶曲线其实就是前面讲解过的lineTo。** - -**二阶曲线原理:** - -二阶曲线由两个数据点(A 和 C),一个控制点(B)来描述曲线状态,大致如下: - -![](http://ww3.sinaimg.cn/large/005Xtdi2jw1f35p4913k7j308c0dw74d.jpg) - -上图中红色曲线部分就是传说中的二阶贝塞尔曲线,那么这条红色曲线是如何生成的呢?接下来我们就以其中的一个状态分析一下: - -![](http://ww4.sinaimg.cn/large/005Xtdi2jw1f361bjqj2vj308c0dwwem.jpg) - -连接AB BC,并在AB上取点D,BC上取点E,使其满足条件: - - -![](http://ww2.sinaimg.cn/large/005Xtdi2jw1f361oje6h1j308c0dwdg0.jpg) - -连接DE,取点F,使得: - - -这样获取到的点F就是贝塞尔曲线上的一个点,动态过程如下: - -![](https://upload.wikimedia.org/wikipedia/commons/3/3d/B%C3%A9zier_2_big.gif) - -> **PS: 二阶曲线对应的方法是quadTo** - -**三阶曲线原理:** - -三阶曲线由两个数据点(A 和 D),两个控制点(B 和 C)来描述曲线状态,如下: - -![](http://ww2.sinaimg.cn/large/005Xtdi2gw1f36myeqcu5j308c0dwdg2.jpg) - -三阶曲线计算过程与二阶类似,具体可以见下图动态效果: - -![](https://upload.wikimedia.org/wikipedia/commons/d/db/B%C3%A9zier_3_big.gif) - -> **PS: 三阶曲线对应的方法是cubicTo** - -#### [贝塞尔曲线速查表](https://github.com/GcsSloop/AndroidNote/blob/master/QuickChart/Bessel.md) - -#### 强烈推荐[点击这里](http://bezier.method.ac/)练习贝塞尔曲线,可以加深对贝塞尔曲线的理解程度。 - -### 第二步.了解贝塞尔曲线相关函数使用方法 - -#### 一阶曲线: - -一阶曲线是一条线段,非常简单,可以参见上一篇文章[Path之基本操作](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B5%5DPath_Basic.md),此处就不详细讲解了。 - -#### 二阶曲线: - -通过上面对二阶曲线的简单了解,我们知道二阶曲线是由两个数据点,一个控制点构成,接下来我们就用一个实例来演示二阶曲线是如何运用的。 - -首先,两个数据点是控制贝塞尔曲线开始和结束的位置,比较容易理解,而控制点则是控制贝塞尔的弯曲状态,相对来说比较难以理解,所以本示例重点在于理解贝塞尔曲线弯曲状态与控制点的关系,废话不多说,先上效果图: - -![](http://ww2.sinaimg.cn/large/005Xtdi2gw1f39vugjg0vg308c0e8409.gif) - -> 为了更加容易看出控制点与曲线弯曲程度的关系,上图中绘制出了辅助点和辅助线,从上面的动态图可以看出,贝塞尔曲线在动态变化过程中有类似于橡皮筋一样的弹性效果,因此在制作一些弹性效果的时候很常用。 - -主要代码如下: - -``` java -public class Bezier extends View { - - private Paint mPaint; - private int centerX, centerY; - - private PointF start, end, control; - - public Bessel1(Context context) { - super(context); - mPaint = new Paint(); - mPaint.setColor(Color.BLACK); - mPaint.setStrokeWidth(8); - mPaint.setStyle(Paint.Style.STROKE); - mPaint.setTextSize(60); - - start = new PointF(0,0); - end = new PointF(0,0); - control = new PointF(0,0); - } - - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - super.onSizeChanged(w, h, oldw, oldh); - centerX = w/2; - centerY = h/2; - - // 初始化数据点和控制点的位置 - start.x = centerX-200; - start.y = centerY; - end.x = centerX+200; - end.y = centerY; - control.x = centerX; - control.y = centerY-100; - } - - @Override - public boolean onTouchEvent(MotionEvent event) { - // 根据触摸位置更新控制点,并提示重绘 - control.x = event.getX(); - control.y = event.getY(); - invalidate(); - return true; - } - - @Override - protected void onDraw(Canvas canvas) { - super.onDraw(canvas); - - // 绘制数据点和控制点 - mPaint.setColor(Color.GRAY); - mPaint.setStrokeWidth(20); - canvas.drawPoint(start.x,start.y,mPaint); - canvas.drawPoint(end.x,end.y,mPaint); - canvas.drawPoint(control.x,control.y,mPaint); - - // 绘制辅助线 - mPaint.setStrokeWidth(4); - canvas.drawLine(start.x,start.y,control.x,control.y,mPaint); - canvas.drawLine(end.x,end.y,control.x,control.y,mPaint); - - // 绘制贝塞尔曲线 - mPaint.setColor(Color.RED); - mPaint.setStrokeWidth(8); - - Path path = new Path(); - - path.moveTo(start.x,start.y); - path.quadTo(control.x,control.y,end.x,end.y); - - canvas.drawPath(path, mPaint); - } -} - -``` - -#### 三阶曲线: -三阶曲线由两个数据点和两个控制点来控制曲线状态。 - -![](http://ww1.sinaimg.cn/large/005Xtdi2gw1f3bmilt4flg308c0e8q5e.gif) - -代码: - -``` java -public class Bezier2 extends View { - - private Paint mPaint; - private int centerX, centerY; - - private PointF start, end, control1, control2; - private boolean mode = true; - - public Bezier2(Context context) { - this(context, null); - - } - - public Bezier2(Context context, AttributeSet attrs) { - super(context, attrs); - - mPaint = new Paint(); - mPaint.setColor(Color.BLACK); - mPaint.setStrokeWidth(8); - mPaint.setStyle(Paint.Style.STROKE); - mPaint.setTextSize(60); - - start = new PointF(0, 0); - end = new PointF(0, 0); - control1 = new PointF(0, 0); - control2 = new PointF(0, 0); - } - - public void setMode(boolean mode) { - this.mode = mode; - } - - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - super.onSizeChanged(w, h, oldw, oldh); - centerX = w / 2; - centerY = h / 2; - - // 初始化数据点和控制点的位置 - start.x = centerX - 200; - start.y = centerY; - end.x = centerX + 200; - end.y = centerY; - control1.x = centerX; - control1.y = centerY - 100; - control2.x = centerX; - control2.y = centerY - 100; - - } - - @Override - public boolean onTouchEvent(MotionEvent event) { - // 根据触摸位置更新控制点,并提示重绘 - if (mode) { - control1.x = event.getX(); - control1.y = event.getY(); - } else { - control2.x = event.getX(); - control2.y = event.getY(); - } - invalidate(); - return true; - } - - @Override - protected void onDraw(Canvas canvas) { - super.onDraw(canvas); - //drawCoordinateSystem(canvas); - - // 绘制数据点和控制点 - mPaint.setColor(Color.GRAY); - mPaint.setStrokeWidth(20); - canvas.drawPoint(start.x, start.y, mPaint); - canvas.drawPoint(end.x, end.y, mPaint); - canvas.drawPoint(control1.x, control1.y, mPaint); - canvas.drawPoint(control2.x, control2.y, mPaint); - - // 绘制辅助线 - mPaint.setStrokeWidth(4); - canvas.drawLine(start.x, start.y, control1.x, control1.y, mPaint); - canvas.drawLine(control1.x, control1.y,control2.x, control2.y, mPaint); - canvas.drawLine(control2.x, control2.y,end.x, end.y, mPaint); - - // 绘制贝塞尔曲线 - mPaint.setColor(Color.RED); - mPaint.setStrokeWidth(8); - - Path path = new Path(); - - path.moveTo(start.x, start.y); - path.cubicTo(control1.x, control1.y, control2.x,control2.y, end.x, end.y); - - canvas.drawPath(path, mPaint); - } -} - -``` - -> 三阶曲线相比于二阶曲线可以制作更加复杂的形状,但是对于高阶的曲线,用低阶的曲线组合也可达到相同的效果,就是传说中的**降阶**。因此我们对贝塞尔曲线的封装方法一般最高只到三阶曲线。 - -#### 降阶与升阶 - -类型 | 释义 | 变化 ------|---|--- -降阶 | 在保持曲线形状与方向不变的情况下,减少控制点数量,即降低曲线阶数 | 方法变得简单,数据点变多,控制点可能减少,灵活性变弱 -升阶 | 在保持曲线形状与方向不变的情况下,增加控制点数量,即升高曲线阶数 | 方法更加复杂,数据点不变,控制点增加,灵活性变强 - -### 第三步.贝塞尔曲线使用实例 - -**在制作这个实例之前,首先要明确一个内容,就是在什么情况下需要使用贝塞尔曲线?** - -> 需要绘制不规则图形时? 当然不是!目前来说,我觉得使用贝塞尔曲线主要有以下几个方面(仅个人拙见,可能存在错误,欢迎指正) - -序号 | 内容 | 用例 ------|-----------------------------------------------|--------- - 1 | 事先不知道曲线状态,需要实时计算时 | 天气预报气温变化的平滑折线图 - 2 | 显示状态会根据用户操作改变时 | QQ小红点,仿真翻书效果 - 3 | 一些比较复杂的运动状态(配合PathMeasure使用) | 复杂运动状态的动画效果 - -至于只需要一个静态的曲线图形的情况,用图片岂不是更好,大量的计算会很不划算。 - -如果是显示SVG矢量图的话,已经有相关的解析工具了(内部依旧运用的有贝塞尔曲线),不需要手动计算。 - -**贝塞尔曲线的主要优点是可以实时控制曲线状态,并可以通过改变控制点的状态实时让曲线进行平滑的状态变化。** - -### 接下来我们就用一个简单的示例让一个圆渐变成为心形: - -#### 效果图: - -![](http://ww2.sinaimg.cn/large/005Xtdi2jw1f3cg2cs7lyg308c0e8gpn.gif) - -#### 思路分析: - -我们最终的需要的效果是将一个圆转变成一个心形,通过分析可知,圆可以由四段三阶贝塞尔曲线组合而成,如下: - -![](http://ww3.sinaimg.cn/large/005Xtdi2gw1f3chnpgub3j308c0e7weq.jpg) - -心形也可以由四段的三阶的贝塞尔曲线组成,如下: - -![](http://ww2.sinaimg.cn/large/005Xtdi2gw1f3chod09sbj308c0e774j.jpg) - -两者的差别仅仅在于数据点和控制点位置不同,因此只需要调整数据点和控制点的位置,就能将圆形变为心形。 - -#### 核心难点: - -##### 1.如何得到数据点和控制点的位置? - - 关于使用绘制圆形的数据点与控制点早就已经有人详细的计算好了,可以参考stackoverflow的一个回答[How to create circle with Bézier curves?](http://stackoverflow.com/questions/1734745/how-to-create-circle-with-b%C3%A9zier-curves)其中的数据只需要拿来用即可。 - - 而对于心形的数据点和控制点,可以由圆形的部分数据点和控制点平移后得到,具体参数可以自己慢慢调整到一个满意的效果。 - -##### 2.如何达到渐变效果? - - 渐变其实就是每次对数据点和控制点稍微移动一点,然后重绘界面,在短时间多次的调整数据点与控制点,使其逐渐接近目标值,通过不断的重绘界面达到一种渐变的效果。过程可以参照下图动态效果: - - ![](http://ww2.sinaimg.cn/large/005Xtdi2jw1f3ch74ewiig308c0e8wic.gif) - -#### 代码: - -``` java -public class Bezier3 extends View { - private static final float C = 0.551915024494f; // 一个常量,用来计算绘制圆形贝塞尔曲线控制点的位置 - - private Paint mPaint; - private int mCenterX, mCenterY; - - private PointF mCenter = new PointF(0,0); - private float mCircleRadius = 200; // 圆的半径 - private float mDifference = mCircleRadius*C; // 圆形的控制点与数据点的差值 - - private float[] mData = new float[8]; // 顺时针记录绘制圆形的四个数据点 - private float[] mCtrl = new float[16]; // 顺时针记录绘制圆形的八个控制点 - - private float mDuration = 1000; // 变化总时长 - private float mCurrent = 0; // 当前已进行时长 - private float mCount = 100; // 将时长总共划分多少份 - private float mPiece = mDuration/mCount; // 每一份的时长 - - - public Bezier3(Context context) { - this(context, null); - - } - - public Bezier3(Context context, AttributeSet attrs) { - super(context, attrs); - - mPaint = new Paint(); - mPaint.setColor(Color.BLACK); - mPaint.setStrokeWidth(8); - mPaint.setStyle(Paint.Style.STROKE); - mPaint.setTextSize(60); - - - // 初始化数据点 - - mData[0] = 0; - mData[1] = mCircleRadius; - - mData[2] = mCircleRadius; - mData[3] = 0; - - mData[4] = 0; - mData[5] = -mCircleRadius; - - mData[6] = -mCircleRadius; - mData[7] = 0; - - // 初始化控制点 - - mCtrl[0] = mData[0]+mDifference; - mCtrl[1] = mData[1]; - - mCtrl[2] = mData[2]; - mCtrl[3] = mData[3]+mDifference; - - mCtrl[4] = mData[2]; - mCtrl[5] = mData[3]-mDifference; - - mCtrl[6] = mData[4]+mDifference; - mCtrl[7] = mData[5]; - - mCtrl[8] = mData[4]-mDifference; - mCtrl[9] = mData[5]; - - mCtrl[10] = mData[6]; - mCtrl[11] = mData[7]-mDifference; - - mCtrl[12] = mData[6]; - mCtrl[13] = mData[7]+mDifference; - - mCtrl[14] = mData[0]-mDifference; - mCtrl[15] = mData[1]; - } - - - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - super.onSizeChanged(w, h, oldw, oldh); - mCenterX = w / 2; - mCenterY = h / 2; - } - - - @Override - protected void onDraw(Canvas canvas) { - super.onDraw(canvas); - drawCoordinateSystem(canvas); // 绘制坐标系 - - canvas.translate(mCenterX, mCenterY); // 将坐标系移动到画布中央 - canvas.scale(1,-1); // 翻转Y轴 - - drawAuxiliaryLine(canvas); - - - // 绘制贝塞尔曲线 - mPaint.setColor(Color.RED); - mPaint.setStrokeWidth(8); - - Path path = new Path(); - path.moveTo(mData[0],mData[1]); - - path.cubicTo(mCtrl[0], mCtrl[1], mCtrl[2], mCtrl[3], mData[2], mData[3]); - path.cubicTo(mCtrl[4], mCtrl[5], mCtrl[6], mCtrl[7], mData[4], mData[5]); - path.cubicTo(mCtrl[8], mCtrl[9], mCtrl[10], mCtrl[11], mData[6], mData[7]); - path.cubicTo(mCtrl[12], mCtrl[13], mCtrl[14], mCtrl[15], mData[0], mData[1]); - - canvas.drawPath(path, mPaint); - - mCurrent += mPiece; - if (mCurrent < mDuration){ - - mData[1] -= 120/mCount; - mCtrl[7] += 80/mCount; - mCtrl[9] += 80/mCount; - - mCtrl[4] -= 20/mCount; - mCtrl[10] += 20/mCount; - - postInvalidateDelayed((long) mPiece); - } - } - - // 绘制辅助线 - private void drawAuxiliaryLine(Canvas canvas) { - // 绘制数据点和控制点 - mPaint.setColor(Color.GRAY); - mPaint.setStrokeWidth(20); - - for (int i=0; i<8; i+=2){ - canvas.drawPoint(mData[i],mData[i+1], mPaint); - } - - for (int i=0; i<16; i+=2){ - canvas.drawPoint(mCtrl[i], mCtrl[i+1], mPaint); - } - - - // 绘制辅助线 - mPaint.setStrokeWidth(4); - - for (int i=2, j=2; i<8; i+=2, j+=4){ - canvas.drawLine(mData[i],mData[i+1],mCtrl[j],mCtrl[j+1],mPaint); - canvas.drawLine(mData[i],mData[i+1],mCtrl[j+2],mCtrl[j+3],mPaint); - } - canvas.drawLine(mData[0],mData[1],mCtrl[0],mCtrl[1],mPaint); - canvas.drawLine(mData[0],mData[1],mCtrl[14],mCtrl[15],mPaint); - } - - // 绘制坐标系 - private void drawCoordinateSystem(Canvas canvas) { - canvas.save(); // 绘制做坐标系 - - canvas.translate(mCenterX, mCenterY); // 将坐标系移动到画布中央 - canvas.scale(1,-1); // 翻转Y轴 - - Paint fuzhuPaint = new Paint(); - fuzhuPaint.setColor(Color.RED); - fuzhuPaint.setStrokeWidth(5); - fuzhuPaint.setStyle(Paint.Style.STROKE); - - canvas.drawLine(0, -2000, 0, 2000, fuzhuPaint); - canvas.drawLine(-2000, 0, 2000, 0, fuzhuPaint); - - canvas.restore(); - } -} - -``` - -## 三.总结 - -其实关于贝塞尔曲线最重要的是核心理解贝塞尔曲线的生成方式,只有理解了贝塞尔曲线的生成方式,才能更好的运用贝塞尔曲线。在上一篇末尾说本篇要涉及一点自相交图形渲染问题,不幸的是,本篇没有了,请期待下一篇(可能会在下一篇中出现o(* ̄︶ ̄*)o),下一篇依旧Path相关内容,教给大家一些更好玩的东西。 - -解锁新的境界之[【绘制一个弹性的圆】](http://www.jianshu.com/p/791d3a791ec2): - - - -(,,• ₃ •,,) -#### PS: 由于本人水平有限,某些地方可能存在误解或不准确,如果你对此有疑问可以提交Issues进行反馈。 - -## About Me - -### 作者微博: @GcsSloop - - - -## 参考资料 -[Path](http://developer.android.com/reference/android/graphics/Path.html)
-[Canvas](http://developer.android.com/reference/android/graphics/Canvas.html)
-[贝塞尔曲线扫盲](http://www.html-js.com/article/1628)
-[贝塞尔曲线-维基百科](https://zh.wikipedia.org/wiki/%E8%B2%9D%E8%8C%B2%E6%9B%B2%E7%B7%9A)
-[How to create circle with Bézier curves?](http://stackoverflow.com/questions/1734745/how-to-create-circle-with-b%C3%A9zier-curves)
-[三次贝塞尔曲线练习之弹性的圆](http://www.jianshu.com/p/791d3a791ec2)
- - - - - - diff --git a/CustomView/Advance/[7]Path_Over.md b/CustomView/Advance/[7]Path_Over.md deleted file mode 100644 index 88cbd1b7..00000000 --- a/CustomView/Advance/[7]Path_Over.md +++ /dev/null @@ -1,412 +0,0 @@ -# Path之完结篇(伪) - -### 作者微博: [@GcsSloop](http://weibo.com/GcsSloop) -### [【本系列相关文章】](https://github.com/GcsSloop/AndroidNote/tree/master/CustomView) - -经历过前两篇 [Path之基本操作](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B5%5DPath_Basic.md) 和 [Path之贝塞尔曲线](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B6%5DPath_Bezier.md) 的讲解,本篇终于进入Path的收尾篇,本篇结束后Path的大部分相关方法都已经讲解完了,但Path还有一些更有意思的玩法,应该会在后续的文章中出现吧,嗯,应该会的ˊ_>ˋ - -****** - -## 一.Path常用方法表 -> 为了兼容性(_偷懒_) 本表格中去除了在API21(即安卓版本5.0)以上才添加的方法。忍不住吐槽一下,为啥看起来有些顺手就能写的重载方法要等到API21才添加上啊。宝宝此刻内心也是崩溃的。 - -作用 | 相关方法 | 备注 -----------------|-----------------|------------------------------------------ -移动起点 | moveTo | 移动下一次操作的起点位置 -设置终点 | setLastPoint | 重置当前path中最后一个点位置,如果在绘制之前调用,效果和moveTo相同 -连接直线 | lineTo | 添加上一个点到当前点之间的直线到Path -闭合路径 | close | 连接第一个点连接到最后一个点,形成一个闭合区域 -添加内容 | addRect, addRoundRect, addOval, addCircle, addPath, addArc, arcTo | 添加(矩形, 圆角矩形, 椭圆, 圆, 路径, 圆弧) 到当前Path (注意addArc和arcTo的区别) -是否为空 | isEmpty | 判断Path是否为空 -是否为矩形 | isRect | 判断path是否是一个矩形 -替换路径 | set | 用新的路径替换到当前路径所有内容 -偏移路径 | offset | 对当前路径之前的操作进行偏移(不会影响之后的操作) -贝塞尔曲线 | quadTo, cubicTo | 分别为二次和三次贝塞尔曲线的方法 -rXxx方法 | rMoveTo, rLineTo, rQuadTo, rCubicTo | **不带r的方法是基于原点的坐标系(偏移量), rXxx方法是基于当前点坐标系(偏移量)** -填充模式 | setFillType, getFillType, isInverseFillType, toggleInverseFillType | 设置,获取,判断和切换填充模式 -提示方法 | incReserve | 提示Path还有多少个点等待加入**(这个方法貌似会让Path优化存储结构)** -布尔操作(API19) | op | 对两个Path进行布尔运算(即取交集、并集等操作) -计算边界 | computeBounds | 计算Path的边界 -重置路径 | reset, rewind | 清除Path中的内容
**reset不保留内部数据结构,但会保留FillType.**
**rewind会保留内部的数据结构,但不保留FillType** -矩阵操作 | transform | 矩阵变换 - - -## 二、Path方法详解 - -### rXxx方法 - -此类方法可以看到和前面的一些方法看起来很像,只是在前面多了一个r,那么这个rXxx和前面的一些方法有什么区别呢? - -> **rXxx方法的坐标使用的是相对位置(基于当前点的位移),而之前方法的坐标是绝对位置(基于当前坐标系的坐标)。** - -**举个例子:** - -``` java - Path path = new Path(); - - path.moveTo(100,100); - path.lineTo(100,200); - - canvas.drawPath(path,mDeafultPaint); -``` -![](http://ww2.sinaimg.cn/large/005Xtdi2gw1f43livlg7ej308c0etmx4.jpg) - -在这个例子中,先移动点到坐标(100,100)处,之后再连接 _点(100,100)_ 到 _(100,200)_ 之间点直线,非常简单,画出来就是一条竖直的线,那接下来看下一个例子: - -``` java - Path path = new Path(); - - path.moveTo(100,100); - path.rLineTo(100,200); - - canvas.drawPath(path,mDeafultPaint); -``` -![](http://ww4.sinaimg.cn/large/005Xtdi2gw1f43lj76wckj308c0etaa1.jpg) - -这个例子中,将 lineTo 换成了 rLineTo 可以看到在屏幕上原本是竖直的线变成了倾斜的线。这是因为最终我们连接的是 _(100,100)_ 和 _(200, 300)_ 之间的线段。 - -在使用rLineTo之前,当前点的位置在 (100,100) , 使用了 rLineTo(100,200) 之后,下一个点的位置是在当前点的基础上加上偏移量得到的,即 (100+100, 100+200) 这个位置,故最终结果如上所示。 - -**PS: 此处仅以 rLineTo 为例,只要理解 “绝对坐标” 和 “相对坐标” 的区别,其他方法类比即可。** - -### 填充模式 - -我们在之前的文章中了解到,Paint有三种样式,“描边” “填充” 以及 “描边加填充”,我们这里所了解到就是在Paint设置为后两种样式时**不同的填充模式对图形渲染效果的影响**。 - -**我们要给一个图形内部填充颜色,首先需要分清哪一部分是外部,哪一部分是内部,机器不像我们人那么聪明,机器是如何判断内外呢?** - -机器判断图形内外,一般有以下两种方法: - -> PS:此处所有的图形均为封闭图形,不包括图形不封闭这种情况。 - -方法 | 判定条件 | 解释 ----------------|-----------------------------------------------|---------------- -奇偶规则 | 奇数表示在图形内,偶数表示在图形外 | 从任意位置p作一条射线, 若与该射线相交的图形边的数目为奇数,则p是图形内部点,否则是外部点。 -非零环绕数规则 | 若环绕数为0表示在图形外,非零表示在图形内 | 首先使图形的边变为矢量。将环绕数初始化为零。再从任意位置p作一条射线。当从p点沿射线方向移动时,对在每个方向上穿过射线的边计数,每当图形的边从右到左穿过射线时,环绕数加1,从左到右时,环绕数减1。处理完图形的所有相关边之后,若环绕数为非零,则p为内部点,否则,p是外部点。 - -接下来我们先了解一下两种判断方法是如何工作的。 - -#### 奇偶规则(Even-Odd Rule) - -这一个比较简单,也容易理解,直接用一个简单示例来说明。 - -![](http://ww4.sinaimg.cn/large/005Xtdi2jw1f417d963qxj308c0dwq33.jpg) - -在上图中有一个四边形,我们选取了三个点来判断这些点是否在图形内部。 - -> -P1: 从P1发出一条射线,发现图形与该射线相交边数为0,偶数,故P1点在图形外部。
-P2: 从P2发出一条射线,发现图形与该射线相交边数为1,奇数,故P2点在图形内部。
-P3: 从P3发出一条射线,发现图形与该射线相交边数为2,偶数,故P3点在图形外部。
- - -#### 非零环绕数规则(Non-Zero Winding Number Rule) - -非零环绕数规则相对来说比较难以理解一点。 - -我们在之前的文章 [Path之基本操作](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B5%5DPath_Basic.md) 中我们了解到,在给Path中添加图形时需要指定图形的添加方式,是用顺时针还是逆时针,另外我们不论是使用lineTo,quadTo,cubicTo还是其他连接线的方法,都是从一个点连接到另一个点,换言之,**Path中任何线段都是有方向性的**,这也是使用非零环绕数规则的基础。 - -我们依旧用一个简单的例子来说明非零环绕数规则的用法: - -> **PS: 注意图形中线段的方向性!** - -![](http://ww2.sinaimg.cn/large/005Xtdi2jw1f42368af2jj308c0dwt8z.jpg) - -> -P1: 从P1点发出一条射线,沿射线防线移动,并没有与边相交点部分,环绕数为0,故P1在图形外边。
-P2: 从P2点发出一条射线,沿射线方向移动,与图形点左侧边相交,该边从左到右穿过穿过射线,环绕数-1,最终环绕数为-1,故P2在图形内部。
-P3: 从P3点发出一条射线,沿射线方向移动,在第一个交点处,底边从右到左穿过射线,环绕数+1,在第二个交点处,右侧边从左到右穿过射线,环绕数-1,最终环绕数为0,故P3在图形外部。
- -通常,这两种方法的判断结果是相同的,但也存在两种方法判断结果不同的情况,如下面这种情况: - -> 注意图形线段的方向,就不详细解释了,用上面的方法进行判断即可。 - -![](http://ww1.sinaimg.cn/large/005Xtdi2gw1f42cvwvlr7j308c0dwgm8.jpg) - -#### 自相交图形 - -**自相交图形定义:多边形在平面内除顶点外还有其他公共点。** - -简单的提一下自相交图形,了解概念即可,下图就是一个简单的自相交图形: - -![](http://ww3.sinaimg.cn/large/005Xtdi2gw1f42dp5drq4j308c0dw74b.jpg) - -#### Android中的填充模式 - -Android中的填充模式有四种,是封装在Path中的一个枚举。 - -模式 | 简介 ------------------|----------------------- -EVEN_ODD | 奇偶规则 -INVERSE_EVEN_ODD | 反奇偶规则 -WINDING | 非零环绕数规则 -INVERSE_WINDING | 反非零环绕数规则 - -我们可以看到上面有四种模式,分成两对,例如 "奇偶规则" 与 "反奇偶规则" 是一对,它们之间有什么关系呢? - -Inverse 和含义是“相反,对立”,说明反奇偶规则刚好与奇偶规则相反,例如对于一个矩形而言,使用奇偶规则会填充矩形内部,而使用反奇偶规则会填充矩形外部,这个会在后面示例中代码展示两者对区别。 - -#### Android与填充模式相关的方法 - -> 这些都是Path中的方法。 - -方法 | 作用 -------------------------|---------------------------- -setFillType | 设置填充规则 -getFillType | 获取当前填充规则 -isInverseFillType | 判断是否是反向(INVERSE)规则 -toggleInverseFillType | 切换填充规则(即原有规则与反向规则之间相互切换) - -#### 示例演示: - -本演示着重于帮助理解填充模式中的一些难点和易混淆的问题,对于一些比较简单的问题,读者可自行验证,本文中不会过多赘述。 - -##### 奇偶规则与反奇偶规则 - -``` java - mDeafultPaint.setStyle(Paint.Style.FILL); // 设置画布模式为填充 - - canvas.translate(mViewWidth / 2, mViewHeight / 2); // 移动画布(坐标系) - - Path path = new Path(); // 创建Path - - //path.setFillType(Path.FillType.EVEN_ODD); // 设置Path填充模式为 奇偶规则 - path.setFillType(Path.FillType.INVERSE_EVEN_ODD); // 反奇偶规则 - - path.addRect(-200,-200,200,200, Path.Direction.CW); // 给Path中添加一个矩形 -``` - -下面两张图片分别是在奇偶规则于反奇偶规则的情况下绘制的结果,可以看出其填充的区域刚好相反: - -> PS: 白色为背景色,黑色为填充色。 - -![](http://ww4.sinaimg.cn/large/005Xtdi2gw1f42jji5nm9j308c0et749.jpg) -![](http://ww1.sinaimg.cn/large/005Xtdi2gw1f42jjtay96j308c0etaa1.jpg) - -##### 图形边的方向对非零奇偶环绕数规则填充结果的影响 - -我们之前讨论过给Path添加图形时顺时针与逆时针的作用,除了上次讲述的方便记录外,就是本文所涉及的另外一个重要作用了: **"作为非零环绕数规则的判断依据。"** - -通过前面我们已经大致了解了在图形边的方向会如何影响到填充效果,我们这里验证一下: - -``` java - mDeafultPaint.setStyle(Paint.Style.FILL); // 设置画笔模式为填充 - - canvas.translate(mViewWidth / 2, mViewHeight / 2); // 移动画布(坐系) - - Path path = new Path(); // 创建Path - - // 添加小正方形 (通过这两行代码来控制小正方形边的方向,从而演示不同的效果) - // path.addRect(-200, -200, 200, 200, Path.Direction.CW); - path.addRect(-200, -200, 200, 200, Path.Direction.CCW); - - // 添加大正方形 - path.addRect(-400, -400, 400, 400, Path.Direction.CCW); - - path.setFillType(Path.FillType.WINDING); // 设置Path填充模式为非零环绕规则 - - canvas.drawPath(path, mDeafultPaint); // 绘制Path -``` - -![](http://ww1.sinaimg.cn/large/005Xtdi2gw1f430h944zhj308c0et3yj.jpg) -![](http://ww3.sinaimg.cn/large/005Xtdi2gw1f430fono6uj308c0et74a.jpg) - - -### 布尔操作(API19) - -布尔操作与我们中学所学的集合操作非常像,只要知道集合操作中等交集,并集,差集等操作,那么理解布尔操作也是很容易的。 - -**布尔操作是两个Path之间的运算,主要作用是用一些简单的图形通过一些规则合成一些相对比较复杂,或难以直接得到的图形**。 - -如太极中的阴阳鱼,如果用贝塞尔曲线制作的话,可能需要六段贝塞尔曲线才行,而在这里我们可以用四个Path通过布尔运算得到,而且会相对来说更容易理解一点。 - -![](http://ww1.sinaimg.cn/large/005Xtdi2jw1f43b9o4yfuj308c0etq2y.jpg) - -``` java - canvas.translate(mViewWidth / 2, mViewHeight / 2); - - Path path1 = new Path(); - Path path2 = new Path(); - Path path3 = new Path(); - Path path4 = new Path(); - - path1.addCircle(0, 0, 200, Path.Direction.CW); - path2.addRect(0, -200, 200, 200, Path.Direction.CW); - path3.addCircle(0, -100, 100, Path.Direction.CW); - path4.addCircle(0, 100, 100, Path.Direction.CCW); - - - path1.op(path2, Path.Op.DIFFERENCE); - path1.op(path3, Path.Op.UNION); - path1.op(path4, Path.Op.DIFFERENCE); - - canvas.drawPath(path1, mDeafultPaint); -``` - -前面演示了布尔运算的作用,接下来我们了解一下布尔运算的核心:布尔逻辑。 - -Path的布尔运算有五种逻辑,如下: - -逻辑名称 | 类比 | 说明 | 示意图 --------------------|------|----------------------------------------|------------------------- -DIFFERENCE | 差集 | Path1中减去Path2后剩下的部分 | ![](http://ww2.sinaimg.cn/large/005Xtdi2gw1f43j85gcaqj305k03c0sn.jpg) -REVERSE_DIFFERENCE | 差集 | Path2中减去Path1后剩下的部分 | ![](http://ww2.sinaimg.cn/large/005Xtdi2gw1f43jbaaw80j305k03c0sn.jpg) -INTERSECT | 交集 | Path1与Path2相交的部分 | ![](http://ww3.sinaimg.cn/large/005Xtdi2gw1f43jbj4iddj305k03c746.jpg) -UNION | 并集 | 包含全部Path1和Path2 | ![](http://ww2.sinaimg.cn/large/005Xtdi2gw1f43jbqk8rbj305k03cmx4.jpg) -XOR | 异或 | 包含Path1与Path2但不包括两者相交的部分 | ![](http://ww3.sinaimg.cn/large/005Xtdi2gw1f43jby8c60j305k03c0sp.jpg) - -#### 布尔运算方法 - -通过前面到理论知识铺垫,相信大家对布尔运算已经有了基本的认识和理解,下面我们用代码演示一下布尔运算: - -在Path中的布尔运算有两个方法 - -``` java - boolean op (Path path, Path.Op op) - boolean op (Path path1, Path path2, Path.Op op) -``` - -两个方法中的返回值用于判断布尔运算是否成功,它们使用方法如下: - -``` `java - // 对 path1 和 path2 执行布尔运算,运算方式由第二个参数指定,运算结果存入到path1中。 - path1.op(path2, Path.Op.DIFFERENCE); - - // 对 path1 和 path2 执行布尔运算,运算方式由第三个参数指定,运算结果存入到path3中。 - path3.op(path1, path2, Path.Op.DIFFERENCE) -``` - -#### 布尔运算示例 - -![](http://ww1.sinaimg.cn/large/005Xtdi2gw1f43jz8xnbxj308c0etwes.jpg) - -代码: - -``` java - int x = 80; - int r = 100; - - canvas.translate(250,0); - - Path path1 = new Path(); - Path path2 = new Path(); - Path pathOpResult = new Path(); - - path1.addCircle(-x, 0, r, Path.Direction.CW); - path2.addCircle(x, 0, r, Path.Direction.CW); - - pathOpResult.op(path1,path2, Path.Op.DIFFERENCE); - canvas.translate(0, 200); - canvas.drawText("DIFFERENCE", 240,0,mDeafultPaint); - canvas.drawPath(pathOpResult,mDeafultPaint); - - pathOpResult.op(path1,path2, Path.Op.REVERSE_DIFFERENCE); - canvas.translate(0, 300); - canvas.drawText("REVERSE_DIFFERENCE", 240,0,mDeafultPaint); - canvas.drawPath(pathOpResult,mDeafultPaint); - - pathOpResult.op(path1,path2, Path.Op.INTERSECT); - canvas.translate(0, 300); - canvas.drawText("INTERSECT", 240,0,mDeafultPaint); - canvas.drawPath(pathOpResult,mDeafultPaint); - - pathOpResult.op(path1,path2, Path.Op.UNION); - canvas.translate(0, 300); - canvas.drawText("UNION", 240,0,mDeafultPaint); - canvas.drawPath(pathOpResult,mDeafultPaint); - - pathOpResult.op(path1,path2, Path.Op.XOR); - canvas.translate(0, 300); - canvas.drawText("XOR", 240,0,mDeafultPaint); - canvas.drawPath(pathOpResult,mDeafultPaint); -``` - -### 计算边界 - -这个方法主要作用是计算Path所占用的空间以及所在位置,方法如下: - -``` java - void computeBounds (RectF bounds, boolean exact) -``` - -它有两个参数: - -参数 | 作用 --------|-------- -bounds | 测量结果会放入这个矩形 -exact | 是否精确测量,目前这一个参数作用已经废弃,一般写true即可。 - -关于exact如有疑问可参见Google官方的提交记录[Path.computeBounds()](https://code.google.com/p/android/issues/detail?id=4070) - -#### 计算边界示例 - -计算path边界的一个简单示例. - -![](http://ww4.sinaimg.cn/large/005Xtdi2gw1f44gxz4k1vj308c0etaa4.jpg) - -代码: - -``` java - // 移动canvas,mViewWidth与mViewHeight在 onSizeChanged 方法中获得 - canvas.translate(mViewWidth/2,mViewHeight/2); - - RectF rect1 = new RectF(); // 存放测量结果的矩形 - - Path path = new Path(); // 创建Path并添加一些内容 - path.lineTo(100,-50); - path.lineTo(100,50); - path.close(); - path.addCircle(-100,0,100, Path.Direction.CW); - - path.computeBounds(rect1,true); // 测量Path - - canvas.drawPath(path,mDeafultPaint); // 绘制Path - - mDeafultPaint.setStyle(Paint.Style.STROKE); - mDeafultPaint.setColor(Color.RED); - canvas.drawRect(rect1,mDeafultPaint); // 绘制边界 -``` - -### 重置路径 - -重置Path有两个方法,分别是reset和rewind,两者区别主要有一下两点: - -方法 | 是否保留FillType设置 | 是否保留原有数据结构 --------|:--------------------:|:--------------------: -reset | 是 | 否 -rewind | 否 | 是 - -**这个两个方法应该何时选择呢?** - -选择权重: FillType > 数据结构 - -_因为“FillType”影响的是显示效果,而“数据结构”影响的是重建速度。_ - - -## 总结 - -Path中常用的方法到此已经结束,希望能够帮助大家加深对Path对理解运用,让大家能够用Path愉快的玩耍。( ̄▽ ̄) - -(,,• ₃ •,,) -#### PS: 由于本人水平有限,某些地方可能存在误解或不准确,如果你对此有疑问可以提交Issues进行反馈。 - -## About Me - -### 作者微博: [@GcsSloop](http://weibo.com/GcsSloop) - - - -## 参考资料 -[Path](https://developer.android.com/reference/android/graphics/Path.html)
-[维基百科-Nonzero-rule](https://en.wikipedia.org/wiki/Nonzero-rule)
-[android绘图之Path总结](http://ghui.me/post/2015/10/android-graphics-path/)
-[布尔逻辑](https://zh.wikipedia.org/wiki/%E5%B8%83%E5%B0%94%E9%80%BB%E8%BE%91)
-[GoogleCode-Path.computeBounds()](https://code.google.com/p/android/issues/detail?id=4070)
-[Path.reset vs Path.rewind](http://stackoverflow.com/questions/11505617/path-reset-vs-path-rewind)
-[]()
-[]()
- - - - - diff --git a/CustomView/Advance/[8]Path_Play.md b/CustomView/Advance/[8]Path_Play.md deleted file mode 100644 index eeca557b..00000000 --- a/CustomView/Advance/[8]Path_Play.md +++ /dev/null @@ -1,552 +0,0 @@ -# Path之玩出花样(PathMeasure) - -### 作者微博: [@GcsSloop](http://weibo.com/GcsSloop) -### [【本系列相关文章】](https://github.com/GcsSloop/AndroidNote/tree/master/CustomView) - - -可以看到,在经过 -[Path之基本操作](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B5%5DPath_Basic.md) -[Path之贝塞尔曲线](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B6%5DPath_Bezier.md) 和 -[Path之完结篇(伪)](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B7%5DPath_Over.md) 后, Path中各类方法基本上都讲完了,表格中还没有讲解到到方法就是矩阵变换了,难道本篇终于要讲矩阵了? -非也,矩阵这一部分仍在后面单独讲解,本篇主要讲解 PathMeasure 这个类与 Path 的一些使用技巧。 - -> PS:不要问我为什么不讲 PathEffect,因为这个方法在后面的Paint系列中。 - -先放一个图镇楼,省的下面无聊的内容把你们都吓跑了Σ( ̄。 ̄ノ)ノ - -![](http://ww3.sinaimg.cn/large/005Xtdi2jw1f4fp2myqo4g308c05k75k.gif) - -****** - -## Path & PathMeasure - -顾名思义,PathMeasure是一个用来测量Path的类,主要有以下方法: - -### 构造方法 - -方法名 | 释义 ----|--- -PathMeasure() | 创建一个空的PathMeasure -PathMeasure(Path path, boolean forceClosed) | 创建 PathMeasure 并关联一个指定的Path(Path需要已经创建完成)。 - -### 公共方法 - -返回值 | 方法名 | 释义 ---------|--------------------------------------------------------------------------|------------------- -void | setPath(Path path, boolean forceClosed) | 关联一个Path -boolean | isClosed() | 是否闭合 -float | getLength() | 获取Path的长度 -boolean | nextContour() | 跳转到下一个轮廓 -boolean | getSegment(float startD, float stopD, Path dst, boolean startWithMoveTo) | 截取片段 -boolean | getPosTan(float distance, float[] pos, float[] tan) | 获取指定长度的位置坐标及该点切线值 -boolean | getMatrix(float distance, Matrix matrix, int flags) | 获取指定长度的位置坐标及该点Matrix - -PathMeasure的方法也不多,接下来我们就逐一的讲解一下。 - -****** - - -### 1.构造函数 - -构造函数有两个。 - -**无参构造函数:** - -``` java - PathMeasure () -``` - -用这个构造函数可创建一个空的 PathMeasure,但是使用之前需要先调用 setPath 方法来与 Path 进行关联。被关联的 Path 必须是已经创建好的,如果关联之后 Path 内容进行了更改,则需要使用 setPath 方法重新关联。 - -**有参构造函数:** - -``` java - PathMeasure (Path path, boolean forceClosed) -``` - -用这个构造函数是创建一个 PathMeasure 并关联一个 Path, 其实和创建一个空的 PathMeasure 后调用 setPath 进行关联效果是一样的,同样,被关联的 Path 也必须是已经创建好的,如果关联之后 Path 内容进行了更改,则需要使用 setPath 方法重新关联。 - -该方法有两个参数,第一个参数自然就是被关联的 Path 了,第二个参数是用来确保 Path 闭合,如果设置为 true, 则不论之前Path是否闭合,都会自动闭合该 Path(如果Path可以闭合的话)。 - -**在这里有两点需要明确:** - -> -* 1. 不论 forceClosed 设置为何种状态(true 或者 false), 都不会影响原有Path的状态,**即 Path 与 PathMeasure 关联之后,之前的的 Path 不会有任何改变。** -* 2. forceClosed 的设置状态可能会影响测量结果,**如果 Path 未闭合但在与 PathMeasure 关联的时候设置 forceClosed 为 true 时,测量结果可能会比 Path 实际长度稍长一点,获取到到是该 Path 闭合时的状态。** - -下面我们用一个例子来验证一下: - -``` - canvas.translate(mViewWidth/2,mViewHeight/2); - - Path path = new Path(); - - path.lineTo(0,200); - path.lineTo(200,200); - path.lineTo(200,0); - - PathMeasure measure1 = new PathMeasure(path,false); - PathMeasure measure2 = new PathMeasure(path,true); - - Log.e("TAG", "forceClosed=false---->"+measure1.getLength()); - Log.e("TAG", "forceClosed=true----->"+measure2.getLength()); - - canvas.drawPath(path,mDeafultPaint); -``` - -log如下: -``` - 25521-25521/com.gcssloop.canvas E/TAG: forceClosed=false---->600.0 - 25521-25521/com.gcssloop.canvas E/TAG: forceClosed=true----->800.0 -``` - -绘制在界面上的效果如下: - -![](http://ww4.sinaimg.cn/large/005Xtdi2jw1f49allf7gij308c0et3yk.jpg) - -我们所创建的 Path 实际上是一个边长为 200 的正方形的三条边,通过上面的示例就能验证以上两个问题。 - -> -* 1.我们将 Path 与两个的 PathMeasure 进行关联,并给 forceClosed 设置了不同的状态,之后绘制再绘制出来的 Path 没有任何变化,所以与 Path 与 PathMeasure进行关联并不会影响 Path 状态。 -* 2.我们可以看到,设置 forceClosed 为 true 的方法比设置为 false 的方法测量出来的长度要长一点,这是由于 Path 没有闭合的缘故,多出来的距离正是 Path 最后一个点与最开始一个点之间点距离。**forceClosed 为 false 测量的是当前 Path 状态的长度, forceClosed 为 true,则不论Path是否闭合测量的都是 Path 的闭合长度。** - - - - - -### 2.setPath、 isClosed 和 getLength - -这三个方法都如字面意思一样,非常简单,这里就简单是叙述一下,不再过多讲解。 - -setPath 是 PathMeasure 与 Path 关联的重要方法,效果和 构造函数 中两个参数的作用是一样的。 - -isClosed 用于判断 Path 是否闭合,但是如果你在关联 Path 的时候设置 forceClosed 为 true 的话,这个方法的返回值则一定为true。 - -getLength 用于获取 Path 的总长度,在之前的测试中已经用过了。 - - - - - -### 3.getSegment - -getSegment 用于获取Path的一个片段,方法如下: - -``` java - boolean getSegment (float startD, float stopD, Path dst, boolean startWithMoveTo) -``` - -方法各个参数释义: - -参数 | 作用 | 备注 -----------------|----------------------------------|-------------------------------------------- -返回值(boolean) | 判断截取是否成功 | true 表示截取成功,结果存入dst中,false 截取失败,不会改变dst中内容 -startD | 开始截取位置距离 Path 起点的长度 | 取值范围: 0 <= startD < stopD <= Path总长度 -stopD | 结束截取位置距离 Path 起点的长度 | 取值范围: 0 <= startD < stopD <= Path总长度 -dst | 截取的 Path 将会添加到 dst 中 | 注意: 是添加,而不是替换 -startWithMoveTo | 起始点是否使用 moveTo | 用于保证截取的 Path 第一个点位置不变 - -> -* 如果 startD、stopD 的数值不在取值范围 [0, getLength] 内,或者 startD == stopD 则返回值为 false,不会改变 dst 内容。 -* 如果在安卓4.4或者之前的版本,在默认开启硬件加速的情况下,更改 dst 的内容后可能绘制会出现问题,请关闭硬件加速或者给 dst 添加一个单个操作,例如: dst.rLineTo(0, 0) - -我们先看看这个方法如何使用: - -我们创建了一个 Path, 并在其中添加了一个矩形,现在我们想截取矩形中的一部分,就是下图中红色的部分。 - -> 矩形边长400dp,起始点在左上角,顺时针 - -![](http://ww2.sinaimg.cn/large/005Xtdi2jw1f4bohcxzhqj308c0etwej.jpg) - -代码: - -``` java - canvas.translate(mViewWidth / 2, mViewHeight / 2); // 平移坐标系 - - Path path = new Path(); // 创建Path并添加了一个矩形 - path.addRect(-200, -200, 200, 200, Path.Direction.CW); - - Path dst = new Path(); // 创建用于存储截取后内容的 Path - - PathMeasure measure = new PathMeasure(path, false); // 将 Path 与 PathMeasure 关联 - - // 截取一部分存入dst中,并使用 moveTo 保持截取得到的 Path 第一个点的位置不变 - measure.getSegment(200, 600, dst, true); - - canvas.drawPath(dst, mDeafultPaint); // 绘制 dst -``` - -结果如下: - -![](http://ww2.sinaimg.cn/large/005Xtdi2jw1f4bpmetj7wj308c0etdfu.jpg) - -从上图可以看到我们成功到将需要到片段截取了出来,然而当 dst 中有内容时会怎样呢? - -``` java - canvas.translate(mViewWidth / 2, mViewHeight / 2); // 平移坐标系 - - Path path = new Path(); // 创建Path并添加了一个矩形 - path.addRect(-200, -200, 200, 200, Path.Direction.CW); - - Path dst = new Path(); // 创建用于存储截取后内容的 Path - dst.lineTo(-300, -300); // <--- 在 dst 中添加一条线段 - - PathMeasure measure = new PathMeasure(path, false); // 将 Path 与 PathMeasure 关联 - - measure.getSegment(200, 600, dst, true); // 截取一部分 并使用 moveTo 保持截取得到的 Path 第一个点的位置不变 - - canvas.drawPath(dst, mDeafultPaint); // 绘制 Path -``` - -结果如下: - -![](http://ww3.sinaimg.cn/large/005Xtdi2gw1f4cg8rl0wmj308c0et74b.jpg) - -从上面的示例可以看到 dst 中的线段保留了下来,可以得到结论:**被截取的 Path 片段会添加到 dst 中,而不是替换 dst 中到内容。** - -前面两个例子中 startWithMoveTo 均为 true, 如果设置为false会怎样呢? - -``` java - canvas.translate(mViewWidth / 2, mViewHeight / 2); // 平移坐标系 - - Path path = new Path(); // 创建Path并添加了一个矩形 - path.addRect(-200, -200, 200, 200, Path.Direction.CW); - - Path dst = new Path(); // 创建用于存储截取后内容的 Path - dst.lineTo(-300, -300); // 在 dst 中添加一条线段 - - PathMeasure measure = new PathMeasure(path, false); // 将 Path 与 PathMeasure 关联 - - measure.getSegment(200, 600, dst, false); // <--- 截取一部分 不使用 startMoveTo, 保持 dst 的连续性 - - canvas.drawPath(dst, mDeafultPaint); // 绘制 Path -``` - -结果如下: - -![](http://ww2.sinaimg.cn/large/005Xtdi2gw1f4cgdgc7etj308c0et3yk.jpg) - -从该示例我们又可以得到一条结论:**如果 startWithMoveTo 为 true, 则被截取出来到Path片段保持原状,如果 startWithMoveTo 为 false,则会将截取出来的 Path 片段的起始点移动到 dst 的最后一个点,以保证 dst 的连续性。** - -从而我们可以用以下规则来判断 startWithMoveTo 的取值: - -取值 | 主要功用 -------|------------------ -true | 保证截取得到的 Path 片段不会发生形变 -false | 保证存储截取片段的 Path(dst) 的连续性 - - - - - -### 4.nextContour - -我们知道 Path 可以由多条曲线构成,但不论是 getLength , getgetSegment 或者是其它方法,都只会在其中第一条线段上运行,而这个 `nextContour` 就是用于跳转到下一条曲线到方法,_如果跳转成功,则返回 true, 如果跳转失败,则返回 false。_ - -如下,我们创建了一个 Path 并使其中包含了两个闭合的曲线,内部的边长是200,外面的边长是400,现在我们使用 PathMeasure 分别测量两条曲线的总长度。 - -![](http://ww2.sinaimg.cn/large/005Xtdi2jw1f4ctzjr08dj308c0et74c.jpg) - -代码: - -``` java - canvas.translate(mViewWidth / 2, mViewHeight / 2); // 平移坐标系 - - Path path = new Path(); - - path.addRect(-100, -100, 100, 100, Path.Direction.CW); // 添加小矩形 - path.addRect(-200, -200, 200, 200, Path.Direction.CW); // 添加大矩形 - - canvas.drawPath(path,mDeafultPaint); // 绘制 Path - - PathMeasure measure = new PathMeasure(path, false); // 将Path与PathMeasure关联 - - float len1 = measure.getLength(); // 获得第一条路径的长度 - - measure.nextContour(); // 跳转到下一条路径 - - float len2 = measure.getLength(); // 获得第二条路径的长度 - - Log.i("LEN","len1="+len1); // 输出两条路径的长度 - Log.i("LEN","len2="+len2); -``` - -log输出结果: -``` -05-30 02:00:33.899 19879-19879/com.gcssloop.canvas I/LEN: len1=800.0 -05-30 02:00:33.899 19879-19879/com.gcssloop.canvas I/LEN: len2=1600.0 -``` - -通过测试,我们可以得到以下内容: - -* 1.曲线的顺序与 Path 中添加的顺序有关。 -* 2.getLength 获取到到是当前一条曲线分长度,而不是整个 Path 的长度。 -* 3.getLength 等方法是针对当前的曲线(其它方法请自行验证)。 - - - - - -#### 5.getPosTan - -这个方法是用于得到路径上某一长度的位置以及该位置的正切值: -``` java - boolean getPosTan (float distance, float[] pos, float[] tan) -``` - -方法各个参数释义: - -参数 | 作用 | 备注 -----------------|----------------------------------|-------------------------------------------- -返回值(boolean) | 判断获取是否成功 | true表示成功,数据会存入 pos 和 tan 中,
false 表示失败,pos 和 tan 不会改变 -distance | 距离 Path 起点的长度 | 取值范围: 0 <= distance <= getLength -pos | 该点的坐标值 | 坐标值: (x==[0], y==[1]) -tan | 该点的正切值 | 正切值: (x==[0], y==[1]) - -这个方法也不难理解,除了其中 `tan` 这个东东,这个东西是干什么的呢? - -`tan` 是用来判断 Path 的趋势的,即在这个位置上曲线的走向,请看下图示例,注意箭头的方向: - -![](http://ww4.sinaimg.cn/large/005Xtdi2jw1f4dtufydm4g308c0etmyl.gif) - -**[点击这里下载箭头图片](http://ww1.sinaimg.cn/large/005Xtdi2jw1f4gam21ktoj3069069jre.jpg)** - -可以看到 上图中箭头在沿着 Path 运动时,方向始终与 Path 走向保持一致,下面我们来看看代码是如何实现的: - -首先我们需要定义几个必要的变量: - -``` java - private float currentValue = 0; // 用于纪录当前的位置,取值范围[0,1]映射Path的整个长度 - - private float[] pos; // 当前点的实际位置 - private float[] tan; // 当前点的tangent值,用于计算图片所需旋转的角度 - private Bitmap mBitmap; // 箭头图片 - private Matrix mMatrix; // 矩阵,用于对图片进行一些操作 -``` - -初始化这些变量(在构造函数中调用这个方法): - -``` java - private void init(Context context) { - pos = new float[2]; - tan = new float[2]; - BitmapFactory.Options options = new BitmapFactory.Options(); - options.inSampleSize = 2; // 缩放图片 - mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.arrow, options); - mMatrix = new Matrix(); - } -``` - -具体绘制: - -``` java - - canvas.translate(mViewWidth / 2, mViewHeight / 2); // 平移坐标系 - - Path path = new Path(); // 创建 Path - - path.addCircle(0, 0, 200, Path.Direction.CW); // 添加一个圆形 - - PathMeasure measure = new PathMeasure(path, false); // 创建 PathMeasure - - currentValue += 0.005; // 计算当前的位置在总长度上的比例[0,1] - if (currentValue >= 1) { - currentValue = 0; - } - - measure.getPosTan(measure.getLength() * currentValue, pos, tan); // 获取当前位置的坐标以及趋势 - - mMatrix.reset(); // 重置Matrix - float degrees = (float) (Math.atan2(tan[1], tan[0]) * 180.0 / Math.PI); // 计算图片旋转角度 - - mMatrix.postRotate(degrees, mBitmap.getWidth() / 2, mBitmap.getHeight() / 2); // 旋转图片 - mMatrix.postTranslate(pos[0] - mBitmap.getWidth() / 2, pos[1] - mBitmap.getHeight() / 2); // 将图片绘制中心调整到与当前点重合 - - canvas.drawPath(path, mDeafultPaint); // 绘制 Path - canvas.drawBitmap(mBitmap, mMatrix, mDeafultPaint); // 绘制箭头 - - invalidate(); // 重绘页面 -``` - -**核心要点:** - -> -* 1.**通过 `tan` 得值计算出图片旋转的角度**,tan 是 tangent 的缩写,即中学中常见的正切, 其中tan[0](x)是邻边边长,tan[1](y)是对边边长,而Math中 `atan2` 方法是根据正切是数值计算出该角度的大小,得到的单位是弧度,所以上面又将弧度转为了角度。 -* 2.**通过 `Matrix` 来设置图片对旋转角度和位移**,这里使用的方法与前面讲解过对 canvas操作 有些类似,对于 `Matrix` 会在后面专一进行讲解,敬请期待。 -* 3.**页面刷新**,页面刷新此处是在 onDraw 里面调用了 invalidate 方法来保持界面不断刷新,但并不提倡这么做,正确对做法应该是使用 线程 或者 ValueAnimator 来控制界面的刷新,关于控制页面刷新这一部分会在后续的 动画部分 详细讲解,同样敬请期待。 - - - - -### 6.getMatrix - -这个方法是用于得到路径上某一长度的位置以及该位置的正切值的矩阵: -``` java -boolean getMatrix (float distance, Matrix matrix, int flags) -``` - -方法各个参数释义: - -参数 | 作用 | 备注 -----------------|----------------------------------|-------------------------------------------- -返回值(boolean) | 判断获取是否成功 | true表示成功,数据会存入matrix中,false 失败,matrix内容不会改变 -distance | 距离 Path 起点的长度 | 取值范围: 0 <= distance <= getLength -matrix | 根据 falgs 封装好的matrix | 会根据 flags 的设置而存入不同的内容 -flags | 规定哪些内容会存入到matrix中 | 可选择
POSITION_MATRIX_FLAG(位置)
ANGENT_MATRIX_FLAG(正切) - -其实这个方法就相当于我们在前一个例子中封装 `matrix` 的过程由 `getMatrix` 替我们做了,我们可以直接得到一个封装好到 `matrix`,岂不快哉。 - -但是我们看到最后到 `flags` 选项可以选择 `位置` 或者 `正切` ,如果我们两个选项都想选择怎么办? - -如果两个选项都想选择,可以将两个选项之间用 `|` 连接起来,如下: -``` -measure.getMatrix(distance, matrix, PathMeasure.TANGENT_MATRIX_FLAG | PathMeasure.POSITION_MATRIX_FLAG); -``` - -我们可以将上面都例子中 `getPosTan` 替换为 `getMatrix`, 看看是不是会显得简单很多: - -具体绘制: - -``` java - Path path = new Path(); // 创建 Path - - path.addCircle(0, 0, 200, Path.Direction.CW); // 添加一个圆形 - - PathMeasure measure = new PathMeasure(path, false); // 创建 PathMeasure - - currentValue += 0.005; // 计算当前的位置在总长度上的比例[0,1] - if (currentValue >= 1) { - currentValue = 0; - } - - // 获取当前位置的坐标以及趋势的矩阵 - measure.getMatrix(measure.getLength() * currentValue, mMatrix, PathMeasure.TANGENT_MATRIX_FLAG | PathMeasure.POSITION_MATRIX_FLAG); - - mMatrix.preTranslate(-mBitmap.getWidth() / 2, -mBitmap.getHeight() / 2); // <-- 将图片绘制中心调整到与当前点重合(注意:此处是前乘pre) - - canvas.drawPath(path, mDeafultPaint); // 绘制 Path - canvas.drawBitmap(mBitmap, mMatrix, mDeafultPaint); // 绘制箭头 - - invalidate(); // 重绘页面 -``` - -> 由于此处代码运行结果与上面一样,便不再贴图片了,请参照上面一个示例的效果图。 - -可以看到使用 getMatrix 方法的确可以节省一些代码,不过这里依旧需要注意一些内容: - -> -* 1.对 `matrix` 的操作必须要在 `getMatrix` 之后进行,否则会被 `getMatrix` 重置而导致无效。 -* 2.矩阵对旋转角度默认为图片的左上角,我们此处需要使用 `preTranslate` 调整为图片中心。 -* 3.pre(矩阵前乘) 与 post(矩阵后乘) 的区别,此处请等待后续的文章或者自行搜索。 - -***** - - -## Path & SVG - -我们知道,用Path可以创建出各种个样的图形,但如果图形过于复杂时,用代码写就不现实了,不仅麻烦,而且容易出错,所以在绘制复杂的图形时我们一般是将 SVG 图像转换为 Path。 - -**你说什么是 SVG?** - -SVG 是一种矢量图,内部用的是 xml 格式化存储方式存储这操作和数据,你完全可以将 SVG 看作是 Path 的各项操作简化书写后的存储格式。 - -Path 和 SVG 结合通常能诞生出一些奇妙的东西,如下: - -![](http://ww3.sinaimg.cn/large/005Xtdi2jw1f4g87vfjbeg30690b4go8.gif) -![](http://ww3.sinaimg.cn/large/005Xtdi2jw1f4g89vqhqwg30690b4mzu.gif) - -> -**该图片来自这个开源库 ->[PathView](https://github.com/geftimov/android-pathview)**
-**SVG 转 Path 的解析可以用这个库 -> [AndroidSVG](https://bigbadaboom.github.io/androidsvg/)** - -限于篇幅以及本人精力,这一部分就暂不详解了,感兴趣的可以直接看源码,或者搜索一些相关的解析文章。 - -***** - -## Path使用技巧 - -**话说本篇文章的名字不是叫 玩出花样么?怎么只见前面啰啰嗦嗦的扯了一大堆不明所以的东西,花样在哪里?** - -> -**前面的内容虽然啰嗦繁杂,但却是重中之重的基础,如果在修仙界,这叫根基,而下面讲述的内容的是招式,有了根基才能演化出千变万化的招式,而没有根基只学招式则是徒有其表,只能学一样会一样,很难适应千变万化的需求。** - -先放一个效果图,然后分析一下实现过程: - -![](http://ww3.sinaimg.cn/large/005Xtdi2jw1f4fp2myqo4g308c05k75k.gif) - -这是一个搜索的动效图,通过分析可以得到它应该有四种状态,分别如下: - -状态 |概述 ----------|-------------------------------------------------- -初始状态 | 初始状态,没有任何动效,只显示一个搜索标志 :mag: -准备搜索 | 放大镜图标逐渐变化为一个点 -正在搜索 | 围绕这一个圆环运动,并且线段长度会周期性变化 -准备结束 | 从一个点逐渐变化成为放大镜图标 - -这些状态是有序转换的,转换流程以及转换条件如下: - -> 其中 `正在搜索` 这个状态持续时间长度是不确定的,在没有搜索完成前,应该一直处于搜索状态。 - -![](http://ww4.sinaimg.cn/large/005Xtdi2jw1f4g4i3c06cj30a60gb3yt.jpg) - -简单的分析了其大致的流程之后,就到了制作的重点:对细节对把握。 - -### Path 划分 - -为了制作对方便,此处整个动效用了两个 Path, 一个是中间对放大镜, 另一个则是外侧的圆环,将两者全部画出来是这样子的。 - -![](http://ww4.sinaimg.cn/large/005Xtdi2jw1f4gbhxuuktj308c0etwej.jpg) - -其中 Path 的走向要把握好,如下(只是一个放大镜,并不是♂): - -![](http://ww1.sinaimg.cn/large/005Xtdi2jw1f4gbjj3fd1j308c05kt8i.jpg) - -其中圆形上面的点可以用 PathMeasure 测量,无需计算。 - -### 动画状态与时间关联 - -此处使用的是 ValueAnimator,它可以将一段时间映射到一段数值上,随着时间变化不断的更新数值,并且可以使用插值器开控制数值变化规律(此处使用的是默认插值器)。 - -> PS: 本来不想提前暴露这个的,准备偷偷留到动画部分(。-_-。) 但实在是没有优雅的替代方案了。 - -### 具体绘制 - -绘制部分是根据 当前状态以及从 ValueAnimator 获得的数值来截取 Path 中合适的部分绘制出来。 - -### 最终效果 - -![](http://ww3.sinaimg.cn/large/005Xtdi2jw1f4gbmtj0mvg308c0etq58.gif) - -### 源码 - -上面的内容是为了帮助大家从把控全局流程以及理解某些细节的设计思路,而更多的内容都藏在代码中,代码总体也不算长,感兴趣的可以自己敲一遍。 - -#### [戳这里查看源码](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/Code/SearchView.md) - -> PS: 本代码仅作为示例使用,还有诸多不足,如 自定义属性,视图大小, 点击事件, 监听回调 等,并不适合直接使用,有需要的可以自行补足相关内容。 - - -## 总结 - -**本文中虽然后面的内容看起来比较高大上一点,但前面"啰嗦"的废话才是真正的干货,把前面的东西学会了,后面的各种效果都能信手拈来,如果只研究后面的东西,则是取其形,而难以会其意。** - -#### PS: 由于本人水平有限,某些地方可能存在误解或不准确,如果你对此有疑问可以提交Issues进行反馈。 - -## About Me - -### 作者微博: [@GcsSloop](http://weibo.com/GcsSloop) - - - -## 参考资料 -[PathMeasure](https://developer.android.com/reference/android/graphics/PathMeasure.html)
-[AndroidSVG](https://bigbadaboom.github.io/androidsvg/)
-[android-pathview](https://github.com/geftimov/android-pathview)
-[android Path 和 PathMeasure 进阶](http://blog.csdn.net/cquwentao/article/details/51436852)
-[]()
- - - - - - diff --git a/CustomView/Advance/[99]DrawText.md b/CustomView/Advance/[99]DrawText.md deleted file mode 100644 index fe9982a1..00000000 --- a/CustomView/Advance/[99]DrawText.md +++ /dev/null @@ -1,279 +0,0 @@ -# drawText之坐标、居中、绘制多行 - -本文用于讲解Canvas中关于DrawText相关的一些常见问题,如坐标,居中,和绘制多行。 - -之前由于个人的疏忽以及对问题的想当然,没有进行验证,在 [【安卓自定义View进阶 - 图片文字】](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B4%5DCanvas_PictureText.md) 这篇文章中出现了一个错误,有不少眼睛雪亮的网友都发现了该错误并给予了反馈,非常感谢这些网友的帮助。 - -![](http://ww2.sinaimg.cn/large/005Xtdi2jw1f3i3wsruf7j306o06o3yg.jpg) - -## 错误原因 - -这个错误是drawText方法中坐标的一个问题,就一般的绘图而言,坐标一般都是指定左上角,然而drawText默认并不是左上角,甚至不是大家测试后认为的左下角,而是一个**由Paint中Align决定的对齐基准线**,该API注释原文如下: - -> Draw the text, with origin at (x,y), using the specified paint. **The origin is interpreted based on the Align setting in the paint.** - -在默认情况下基线如下图所示: - -> PS:基线(BaseLine)有两条,是用户指定的坐标确定的,在默认情况下,基线X在字符串左侧,基线y在字符串下方(但并不是最低的部分)。 - -![](http://ww3.sinaimg.cn/large/005Xtdi2gw1f3jppylp6zj30dw08c74v.jpg) - -## 分析这样设计的原因 - -**Q: 为何基线y要放到文字下面,而不是上面?** - -> A : 既然采用这种对齐方式,必然有其缘由,至少不是为了坑我这种小白。据本人猜测可能有以下原因: -* 1.符合人类书写习惯,不论是汉字还是英文或是其他语言,我们在书写对齐的时候都是以下面为基准线的,而不是上面,(**我们默认的基准线类似于四线格中的第三条线**)。
-![](http://ww4.sinaimg.cn/large/005Xtdi2gw1f3knbp87ttj30dw08cq38.jpg)
-* 2.字的特点,字的显示不仅有有中文汉字,还有一些特殊字符,并且大部分是根据下面对齐的,如果把对齐的基线放到上面并使其显示整齐,设计太麻烦,如下:
-![](http://ww1.sinaimg.cn/large/005Xtdi2gw1f3knvptqsrj30dw08cmxw.jpg)
-* 3.字体的特点,我们都知道,字有很多的字体风格,不同字体风格的大小是不同的,如果以以上面为基准线而让其底部对齐,这设计难度简直不敢想象:
-![](http://ww3.sinaimg.cn/large/005Xtdi2gw1f3ko9oln9lj30dw08cmxo.jpg)
-**综上所述,基线y放到下面不仅符合人的书写习惯,而且更加便于设计。** - -## drawText从入门到懵逼 - -虽然之前在 [图片文字](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B4%5DCanvas_PictureText.md) 这篇文章中已经简单的了解部分关于文字的方法,但Paint中关于文字的方法还有很多,本文会了解一些我们比较关心的一些内容,例如绘制居中的文本,多行文本等,在此之前我们先了解一下Paint中与文本相关的内部类或者枚举: - -名称 | 类型 | 主要作用 ----------------|:------:|------------------------------------------------------ -Align | 枚举 | 指定基准线与文本的相对关系(包含 左对齐 右对齐 居中) -Style | 枚举 | 设置样式,但不仅仅是为文本服务(包含 描边 填充 描边加填充) -FontMetrics | 内部类 | 描述给定的文本大小,字体,间距等各种度量值(度量结果类型为float) -FontMetricsInt | 内部类 | 作用同上,但度量结果返回值是int型的 - -### Align - -Align中文意思是对齐,其作用正式如此,我们使用过 Word 的人都知道文本有 *左对齐、居中、右对齐、两端对齐、分散对齐* 五种模式,Align作用就是设置文本的对齐模式,但是并没有这么多,仅有 **左对齐、居中、右对齐** 三种模式,如下: - -> 吐槽:就因为没有两端对齐和分散对齐,导致长文本,尤其是中英混合的长文本在手机上显示效果奇差,相信做阅读类软件的程序员深有体会,最终还要自定义View解决。 - -枚举类型 | 作用 ----------|------------------------------------------------------------- -LEFT | 左对齐 基线X在文本左侧,基线y在文本下方,文本出现在给定坐标的右侧,是默认的对齐方式 -RIGHT | 右对齐 基线x在文本右侧,基线y在文本下方,文本出现在给定坐标的左侧 -CENTER | 居中对齐 基线x在文本中间,基线y在文本下方,文本出现在给定坐标的两侧 - -Align对应的方法如下: - -``` java - public Paint.Align getTextAlign () // 获取对齐方式 - - public void setTextAlign (Paint.Align align) // 设置对齐方式 -``` - -在实际运用中基线与模式之间的关系则如下图所示: - -![](http://ww2.sinaimg.cn/large/005Xtdi2gw1f3l2d6gw0nj30dw08c74q.jpg) - -> PS 该图片是截屏加工所得,其中红色的先是各自的基准线。注意汉字有一部分是在基准线下面的。 - -其核心代码如下: - -``` java - // 平移画布 - 如有疑问请参考画布操作这篇文章 - canvas.translate(mCenterX,0); // mCenterX 是屏幕宽度的一半,在onSizeChanged中获取 - - // 设置字体颜色 - mPaint.setColor(Color.rgb(0x06,0xaf,0xcd)); - - // 在不同模式下绘制文字 - mPaint.setTextAlign(Paint.Align.LEFT); - canvas.drawText("左对齐", 0, 200, mPaint); - - mPaint.setTextAlign(Paint.Align.CENTER); - canvas.drawText("居中对齐", 0, 400, mPaint); - - mPaint.setTextAlign(Paint.Align.RIGHT); - canvas.drawText("右对齐", 0, 600, mPaint); -``` - -### Style - -Style的意思是样式,这个在 [Canvas之绘制基本形状](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B2%5DCanvas_BasicGraphics.md) 这篇文章中讲过,它有三种状态: - -枚举类型 | 作用 -----------------|---------------- -FILL | 填充 -STROKE | 描边 -FILL_AND_STROKE | 填充加描边 - -Style 对应的方法如下: - -``` java -public Paint.Style getStyle () // 获取当然样式 - -public void setStyle (Paint.Style style) // 设置样式 -``` - -效果如下: - -![](http://ww3.sinaimg.cn/large/005Xtdi2gw1f3nh9r8ih0j30dw08c3z4.jpg) - -核心代码: - -``` java - // 平移画布 - 如有疑问请参考画布操作这篇文章 - canvas.translate(mCenterX,0); // mCenterX 是屏幕宽度的一半,在onSizeChanged中获取 - - mPaint.setTextAlign(Paint.Align.CENTER); - mPaint.setColor(Color.rgb(0x06,0xaf,0xcd)); - - // 设置不同的样式 - - // 填充 - mPaint.setStyle(Paint.Style.FILL); - canvas.drawText("GcsSloop 中文", 0, 200, mPaint); - - // 描边 - mPaint.setStyle(Paint.Style.STROKE); - canvas.drawText("GcsSloop 中文", 0, 400, mPaint); - - // 描边加填充 - mPaint.setStyle(Paint.Style.FILL_AND_STROKE); - canvas.drawText("GcsSloop 中文", 0, 600, mPaint); -``` - -### FontMetrics - -FontMetrics 是 Paint 的一个内部类,根据名字我们可以大致知道这是一个描述**字体规格**相关的类,关于这个类的描述原文是这样的: - -> Class that describes the various metrics for a font at a given text size. Remember, Y values increase going down, so those values will be positive, and values that measure distances going up will be negative. This class is returned by getFontMetrics(). - -翻译一下: - -> 简单来说,FontMetrics包含了当前文本相关的各项参数,你可以通过 Paint中 _getFontMetrics()_ 这个方法来获取到这个类。 -(另外,原文中还特地强调了一下关于坐标正负的问题。) - -##### FontMetrics包含了以下几个数值: - -> 如果没有特殊说明,一下文章中“基线”默认代表“基线Y”。 - -名称 | 正负| 释义 ---------|:---:|-------------------------------------------------------- -top | - | 在指定字形和大小的情况下,字符最高点与基线之间的距离 -ascent | - | 单个字符的最高点与基线距离的推荐值(不包括字母上面的符号) -descent | + | 单个字符的最低点与基线距离的推荐值 -bottom | + | 在指定字形和大小的情况下,字符最低点与基线之间的距离 -leading | + | 行间距,当前行bottom与下一行top之间的距离的推荐值 (通常为0,因为top与ascent,bottom与leading之间的距离足够作为行间距了) - -![](http://ww1.sinaimg.cn/large/005Xtdi2gw1f3syr8fbd1j30dw08c755.jpg) - -看了上面啰啰嗦嗦讲了一堆,你可能会产生一些疑问,这里我简单解释一下: - -0、 FontMetrics到底有什么用? - -> FontMetrics 是字体规格,比较精确的测量出文字相关的各种数据,在很多地方都是用得到的,比较常见的就是我们的音乐播放器中的歌词显示,需要实时的变字体位置,这里就需要比较精确是数值来进行计算以确保不会出现两行文字重叠等问题。 - -1、为什么表格中最高点距离基线的值是负值,而最低点反而是正值? - -> 这是因为手机屏幕坐标系的特殊性,在数学中常见的坐标系y轴是向上的,而对于手机而言,y轴默认是向下的,所以数值越小越靠近屏幕顶端,即最高点的数值比基线小,最高点减去基线结果自然为负数。 更多参考 [坐标系](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Base/%5B1%5DCoordinateSystem.md) 这篇文章。 - -2、为什么表格中很多都是推荐值? - -> 这是因为字的规格不仅受字大小的影响,而且受字体风格的影响,不同的字体风格差别很大,其结果可能会有偏差,故大部分都是推荐值。 - -3、 具体绘制的文本不同会影响 FontMetrics 中的数值吗? - -> 不会, **FontMetrics中的数值受字体大小(FontSize) 和 字体风格(Typeface) 影响**, 而不会因为具体绘制的内容不同而改变,给Paint设置完字体大小和字体风格后就能获取到正确的FontMetrics。 - -**获取FontMetrics的方法** -``` java - Paint.FontMetrics mMetrics = mPaint.getFontMetrics(); - - Log.e("TAG", "top=" + mMetrics.top); - Log.e("TAG", "ascent=" + mMetrics.ascent); - Log.e("TAG", "descent=" + mMetrics.descent); - Log.e("TAG", "bottom=" + mMetrics.bottom); - Log.e("TAG", "leading=" + mMetrics.leading); -``` -结果: -``` -05-15 21:18:13.315 13112-13112/com.gcssloop.canvas E/TAG: top=-152.98828 -05-15 21:18:13.315 13112-13112/com.gcssloop.canvas E/TAG: ascent=-129.88281 -05-15 21:18:13.315 13112-13112/com.gcssloop.canvas E/TAG: descent=34.179688 -05-15 21:18:13.315 13112-13112/com.gcssloop.canvas E/TAG: bottom=37.939453 -05-15 21:18:13.315 13112-13112/com.gcssloop.canvas E/TAG: leading=0.0 -``` - -**由于FontMetrics中的 ascent 与 descent 比较常用,所以可以直接通过Paint获取:** -``` java - Log.e("TAG", "P.ascent=" + mPaint.ascent()); - Log.e("TAG", "P.descent=" + mPaint.descent()); -``` -结果,可以看到与通过FontMetrics获得的结果相同。 -``` -05-15 21:24:18.950 13112-13112/com.gcssloop.canvas E/TAG: P.ascent=-129.88281 -05-15 21:24:18.955 13112-13112/com.gcssloop.canvas E/TAG: P.descent=34.179688 -``` - - -## 文字居中 - -对于绘制居中的文本来说,我们可以封装一个方法用中心点作为绘制坐标,在绘制的时候转换为实际坐标。 - -根据前面的知识可知,想让文字水平居中很容易,只需要设置 TextAlign 为 CENTER,那么基线X(BaseLineX)自然就是这个字符串的中心了。 - -而让文字垂直居中则有些麻烦了,因为基线Y(BaseLineY)既不是顶部,底部,也不是中心,所以文本居中最难的内容就是计算BaseLineY的位置。 - -我们已知: - -> 1. 中心位置坐标,centerX, centerY -2. 文本高度:height = descent-ascent -3. descent的坐标:descentY = centerY + 1/2height -4. baseLineY坐标:baseLineY = descentY-descent - -通过上面内容可以推算出如下公式: - -> baseLineY = centerY - 1/2(ascent + descent) - -**根据公式我们可以封装一个方法:** - -``` java - /** - * 居中绘制文本 - * - * @param text - * @param canvas - * @param paint - */ - public void drawTextByCenter(String text, float x, float y, Canvas canvas, Paint paint) { - Paint tempPaint = new Paint(paint); // 创建一个临时画笔,防止影响原来画笔的状态 - tempPaint.setTextAlign(Paint.Align.CENTER); // 设置文本对齐方式为居中 - - // 通过y计算出baseline的位置 - float baseline = y - (tempPaint.descent() + tempPaint.ascent()) / 2; - - canvas.drawText(text, x, baseline, tempPaint); //绘制文本 - } -``` - -**测试方法是否正确** - -``` java - canvas.translate(mCenterX, mCenterY); - - String text = "ASSA"; - mPaint.setColor(Color.BLACK); - - drawTextByCenter(text, 0, 0, canvas, mPaint); -``` - -结果: - - - -## 绘制多行 - -前面讲的所有绘制文本都是绘制单行文本,而对于长文本就束手无策了,但是我们偶尔也需要绘制一些长文本,例如绘制一段文本,这样前面的就无法满足需求了。 - -我们先思考一下如何才能绘制一段长文本让其可以自动换行,如自动测量文本长度,然后根据测量的内容截开成n行,然后一行一行的绘制。 - - - - - - - - - diff --git a/CustomView/Advance/[9]Matrix_Basic.md b/CustomView/Advance/[9]Matrix_Basic.md deleted file mode 100644 index 8aa48f65..00000000 --- a/CustomView/Advance/[9]Matrix_Basic.md +++ /dev/null @@ -1,48 +0,0 @@ -# Matrix基础 - -前面讲了四篇 Path 相关的内容,本次终于要到了大家期盼已久的黑客帝国! - -![](http://ww1.sinaimg.cn/large/005Xtdi2jw1f4oyx5i8wbj308c0bj3zz.jpg) - -如题,本篇的主角是 Matrix(并不是黑客帝国)。 - -它在我们在之前的很多文章中都提及过,但并没有仔细的介绍过,从本篇开始终于要正式介绍它了,这个在2D绘图中十分重要的角色 -- Matrix。 - -> -#### Matrix 的翻译过来是矩阵,模型。和其释义相同,Matrix是一个矩阵,其作用则是一个模型,一个控制视图状态的模型。 - -也就是说, 我们进行界面视图等转换都是需要依靠 Matrix 的帮助的,例如我们之前在 [Canvas之画布操作](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B3%5DCanvas_Convert.md) 中讲解过的画布操作,这些操作的核心就是改变 Matrix 的数值。 - -## Matrix方法表 - -Matrix 有很多常用和不常用的方法,在本篇中重点不在于这些方法的讲解,而是帮助大家理解 Matrix 的一些基本概念。 - -方法类别 | 相关API | 摘要 ------------|---------------------------------------------------------|------------------------ -基本方法 | equals hashCode toString toShortString | 比较、 获取哈希值、 转换为字符串 -数值操作 | set reset setValues getValues | 设置、 重置、 设置数值、 获取数值 -设置(set) | setConcat setRotate setScale setSkew setTranslate | 设置变换 -前乘(pre) | preConcat preRotate preScale preSkew preTranslate | 前乘变换 -后乘(post) | postConcat postRotate postScale postSkew postTranslate | 后乘变换 -数值计算 | mapPoints mapRadius mapRect mapVectors | 计算变换后的数值 -特殊方法 | setPolyToPoly setRectToRect rectStaysRect setSinCos | 一些特殊操作 -矩阵相关 | invert isAffine isIdentity | 求逆矩阵、 是否为仿射矩阵、 是否为单位矩阵 ... - - -## Matrix原理 - -Matrix 本质是一个 3x3 的矩阵,里面有9个数值,分别用于控制视图状态的不同内容,我们对视图的操作最终都是改变Matrix里面的数值。 - - - - - - - - - - - - - - diff --git a/CustomView/Base/[1]CoordinateSystem.md b/CustomView/Base/[1]CoordinateSystem.md deleted file mode 100644 index 2e90e234..00000000 --- a/CustomView/Base/[1]CoordinateSystem.md +++ /dev/null @@ -1,67 +0,0 @@ -# 安卓中的坐标系 - -### 作者微博: [@GcsSloop](http://weibo.com/GcsSloop) -### [【本系列相关文章】](https://github.com/GcsSloop/AndroidNote/tree/master/CustomView) - - -## 一.屏幕坐标系和数学坐标系的区别 -由于移动设备一般定义屏幕左上角为坐标原点,向右为x轴增大方向,向下为y轴增大方向, -所以在手机屏幕上的坐标系与数学中常见的坐标系是稍微有点差别的,详情如下: - -(**PS:其中的∠a 是对应的,注意y轴方向!**) - -![](http://ww2.sinaimg.cn/large/005Xtdi2jw1f1qygzfvhoj308c0dwglr.jpg) -![](http://ww1.sinaimg.cn/large/005Xtdi2jw1f1qyhbqvihj308c0dwjrh.jpg) - -**实际屏幕上的默认坐标系如下:** - -> PS: 假设其中棕色部分为手机屏幕 - -![](http://ww3.sinaimg.cn/large/005Xtdi2jw1f1qyhjy7h8j308c0dwq32.jpg) - -## 二.View的坐标系 - -**注意:View的坐标系统是相对于父控件而言的.** - -``` java - getTop(); //获取子View左上角距父View顶部的距离 - getLeft(); //获取子View左上角距父View左侧的距离 - getBottom(); //获取子View右下角距父View顶部的距离 - getRight(); //获取子View右下角距父View左侧的距离 -``` -**如下图所示:** - -![](http://ww2.sinaimg.cn/large/005Xtdi2gw1f1qzqwvkkbj308c0dwgm9.jpg) - -## 三.MotionEvent中 get 和 getRaw 的区别 -``` - event.getX(); //触摸点相对于其所在组件坐标系的坐标 - event.getY(); - - event.getRawX(); //触摸点相对于屏幕默认坐标系的坐标 - event.getRawY(); - -``` -**如下图所示:** - -> PS:其中相同颜色的内容是对应的,其中为了显示方便,蓝色箭头向左稍微偏移了一点. - -![](http://ww1.sinaimg.cn/large/005Xtdi2jw1f1r2bdlqhbj308c0dwwew.jpg) - -## 四.核心要点 - -序号 | 要点 -:---:|---- - 1 | 在数学中常见的坐标系与屏幕默认坐标系的差别 - 2 | View的坐标系是相对于父控件而言的 - 3 | MotionEvent中get和getRaw的区别 - -## 五.参考文章: -[Android 屏幕(View)坐标系统](http://blog.csdn.net/wangjinyu501/article/details/21827341) - -## About Me - -### 作者微博: @GcsSloop - - - diff --git a/CustomView/Base/[2]AngleAndRadian.md b/CustomView/Base/[2]AngleAndRadian.md deleted file mode 100644 index 295b006c..00000000 --- a/CustomView/Base/[2]AngleAndRadian.md +++ /dev/null @@ -1,74 +0,0 @@ -# 角度与弧度 - -### 作者微博: [@GcsSloop](http://weibo.com/GcsSloop) -### [【本系列相关文章】](https://github.com/GcsSloop/AndroidNote/tree/master/CustomView) - -安卓中角度(angle)与弧度(radian)的有关问题。 - -## 一.前言 - -### 1.为什么讲这个? - - 在我们自定义View,尤其是制作一些复杂炫酷的效果的时候,实际上是将一些简单的东西通过数学上精密的计算组合到一起形成的效果。 - -这其中可能会涉及到画布的相关操作(旋转),以及一些正余弦函数的计算等,这些内容就会用到一些角度、弧度相关的知识。 - -### 2.为什么对角的描述存在角度与弧度两种单位? - -简单来说就是为了方便,为了精确描述一个角的大小引入了角度与弧度的概念。 - -由于两者进制是不同的(**角度是60进制,弧度是10进制**),在合适的地方使用合适的单位来描述会更加方便。 - -> **例如:** -角度是60进位制,遇到30°6′这样的角,应该转化为10进制的30.1°。但弧度就不需要,因为弧度本身就是十进制的实数。 - - -## 二.角度与弧度的定义 - -角度和弧度一样都是描述角的一种度量单位,下面是它们的定义: - -名称 | 定义 -:---:| --- -角度 | 两条射线从圆心向圆周射出,形成一个夹角和夹角正对的一段弧。**当这段弧长正好等于圆周长的360分之一时,两条射线的夹角的大小为1度.** -弧度 | 两条射线从圆心向圆周射出,形成一个夹角和夹角正对的一段弧。**当这段弧长正好等于圆的半径时,两条射线的夹角大小为1弧度.** - -**如图:** - -![](http://ww1.sinaimg.cn/large/005Xtdi2jw1f1s0f975hmj308c0dwmxh.jpg) -![](http://ww3.sinaimg.cn/large/005Xtdi2jw1f1s0g3rcg2j308c0dw3yw.jpg) - - -## 三.角度和弧度的换算关系 -根据角度和弧度的的定义和圆的相关知识非常容易就能得出两者的换算公式: - -先设圆的周长为C. 半径为r - -C = 2πr; - -一周对应的角度为360度(角度),对应的弧度为2π弧度。 - -故: **180度 = π弧度.** - -可得: - -**弧度 = 角度xπ/180** - -**角度 = 弧度x180/π** - - -## 四.一些细节问题 -由于默认屏幕坐标系和常见数学坐标系的小差别([坐标系问题点这里](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Base/%5B1%5DCoordinateSystem.md)),所以在角上必然也会存在一些区别,例如: - -**在常见的数学坐标系中角度增大方向为逆时针,** - -**在默认的屏幕坐标系中角度增大方向为顺时针。** - -![](http://ww3.sinaimg.cn/large/005Xtdi2jw1f1s2wnsewfj308c0dwt94.jpg) - -## About Me -### 作者微博: @GcsSloop - - - - - diff --git a/CustomView/Base/[3]Color.md b/CustomView/Base/[3]Color.md deleted file mode 100644 index d27d00f4..00000000 --- a/CustomView/Base/[3]Color.md +++ /dev/null @@ -1,159 +0,0 @@ -# 颜色 - -### 作者微博: [@GcsSloop](http://weibo.com/GcsSloop) -### [【本系列相关文章】](https://github.com/GcsSloop/AndroidNote/tree/master/CustomView) - -简要介绍安卓中的颜色相关内容,包括颜色的定义,创建颜色的几种方式,以及颜色的混合模式等。 - -## 一.简单介绍颜色 - -安卓支持的颜色模式: - -颜色模式 | 备注 -:--- | --- -ARGB8888 | 四通道高精度(32位) -ARGB4444 | 四通道低精度(16位) -RGB565 | **屏幕默认模式**(16位) -Alpha8 | 仅有透明通道(8位) - -*PS:其中字母表示通道类型,数值表示该类型用多少位二进制来描述。如ARGB8888则表示有四个通道(ARGB),每个对应的通道均用8位来描述。* - -*注意:我们常用的是ARGB8888和ARGB4444,而在所有的安卓设备屏幕上默认的模式都是RGB565,请留意这一点。* - -**以ARGB8888为例介绍颜色定义:** - -类型 | 解释 | 0(0x00) | 255(0xff) -:-------- |:------ | :------ | :-------- -A(Alpha) | 透明度 | 透明 | 不透明 -R(Red) | 红色 | 无色 | 红色 -G(Green) | 绿色 | 无色 | 绿色 -B(Blue) | 蓝色 | 无色 | 蓝色 - -*其中 A R G B 的取值范围均为0~255(即16进制的0x00~0xff)* - -A 从ox00到oxff表示从透明到不透明。 - -RGB 从0x00到0xff表示颜色从浅到深。 - -**当RGB全取最小值(0或0x000000)时颜色为黑色,全取最大值(255或0xffffff)时颜色为白色** - -## 二.几种创建或使用颜色的方式 -### 1.java中定义颜色 -``` java - int color = Color.GRAY; //灰色 -``` - 由于Color类提供的颜色仅为有限的几个,通常还是用ARGB值进行表示。 -``` java - int color = Color.argb(127, 255, 0, 0); //半透明红色 - - int color = 0xaaff0000; //带有透明度的红色 -``` -### 2.在xml文件中定义颜色 -在/res/values/color.xml 文件中如下定义: -``` xml - - - #ff0000 - #00ff00 - -``` -详解: 在以上xml文件中定义了两个颜色,红色和蓝色,是没有alpha(透明)通道的。 - -定义颜色以‘#’开头,后面跟十六进制的值,有如下几种定义方式: -``` java - #f00 //低精度 - 不带透明通道红色 - #af00 //低精度 - 带透明通道红色 - - #ff0000 //高精度 - 不带透明通道红色 - #aaff0000 //高精度 - 带透明通道红色 -``` - -### 3.在java文件中引用xml中定义的颜色: -``` java - int color = getResources().getColor(R.color.mycolor); -``` -### 4.在xml文件(layout或style)中引用或者创建颜色 -``` xml - - -``` -``` java - android:background="@color/red" //引用在/res/values/color.xml 中定义的颜色 - - android:background="#ff0000" //创建并使用颜色 -``` - -## 三.取色工具 -颜色都是用RGB值定义的,而我们一般是无法直观的知道自己需要颜色的值,需要借用取色工具直接从图片或者其他地方获取颜色的RGB值。 - -### 1.屏幕取色工具 -取色调色工具,可以从屏幕取色或者使用调色板调制颜色,非常小而精简。 - -[点击这里获取屏幕取色工具](http://pan.baidu.com/s/1gdWkN0B) - -### 2.Picpick -功能更加强大的工具:PicPick。 - -PicPick具备了截取全屏、活动窗口、指定区域、固定区域、手绘区域功能,支持滚动截屏,屏幕取色,支持双显示器,具备白板、屏幕标尺、直角座标或极座标显示与测量,具备强大的图像编辑和标注功能。 - -[点击这里获取PicPick](http://ngwin.com/picpick) - -## 四.颜色混合模式(Alpha通道相关) - -通过前面介绍我们知道颜色一般都是四个通道(ARGB)的,其中(RGB)控制的是颜色,而A(Alpha)控制的是透明度。 - -因为我们的显示屏是没法透明的,因此最终显示在屏幕上的颜色里可以认为没有Alpha通道。Alpha通道主要在两个图像混合的时候生效。 - -默认情况下,当一个颜色绘制到Canvas上时的混合模式是这样计算的: - -**(RGB通道) 最终颜色 = 绘制的颜色 + (1 - 绘制颜色的透明度) × Canvas上的原有颜色。** - -注意: - -1.这里我们一般把每个通道的取值从0(ox00)到255(0xff)映射到0到1的浮点数表示。 - -2.这里等式右边的“绘制的颜色"、“Canvas上的原有颜色”都是经过预乘了自己的Alpha通道的值。如绘制颜色:0x88ffffff,那么参与运算时的每个颜色通道的值不是1.0,而是(1.0 * 0.5333 = 0.5333)。 (其中0.5333 = 0x88/0xff) - -使用这种方式的混合,就会造成后绘制的内容以半透明的方式叠在上面的视觉效果。 - -其实还可以有不同的混合模式供我们选择,用Paint.setXfermode,指定不同的PorterDuff.Mode。 - -下表是各个PorterDuff模式的混合计算公式:(D指原本在Canvas上的内容dst,S指绘制输入的内容src,a指alpha通道,c指RGB各个通道) - -混合模式 | 计算公式 - ------- | --------- -ADD | Saturate(S + D) -CLEAR | [0, 0] -DARKEN | [Sa + Da - Sa*Da, Sc*(1 - Da) + Dc*(1 - Sa) + min(Sc, Dc)] -DST | [Da, Dc] -DST_ATOP | [Sa, Sa * Dc + Sc * (1 - Da)] -DST_IN | [Sa * Da, Sa * Dc] -DST_OUT | [Da * (1 - Sa), Dc * (1 - Sa)] -DST_OVER | [Sa + (1 - Sa)*Da, Rc = Dc + (1 - Da)*Sc] -LIGHTEN | [Sa + Da - Sa*Da, Sc*(1 - Da) + Dc*(1 - Sa) + max(Sc, Dc)] -MULTIPLY | [Sa * Da, Sc * Dc] -SCREEN | [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] -SRC | [Sa, Sc] -SRC_ATOP | [Da, Sc * Da + (1 - Sa) * Dc] -SRC_IN | [Sa * Da, Sc * Da] -SRC_OUT | [Sa * (1 - Da), Sc * (1 - Da)] -SRC_OVER | [Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc] -XOR | [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc] - -用示例图来查看使用不同模式时的混合效果如下(src表示输入的图,dst表示原Canvas上的内容): - -![](http://ww4.sinaimg.cn/large/005Xtdi2gw1f1wa0f0mzjj30hh0fsjt8.jpg) - - -## 五.参考资料 - -[【安卓图形动画】](http://www.cnblogs.com/zhucai/p/android-graphics-animation.html) - -## About Me -### 作者微博: @GcsSloop - - - - diff --git a/CustomView/README.md b/CustomView/README.md deleted file mode 100644 index 485bd509..00000000 --- a/CustomView/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# 自定义View系列 - -从零起步,从入门到懵逼的自定义View教程。 - -## 基础篇 - -

- - - -

- -******* - -## 进阶篇 -

- - - -

- -******* - -

- - - -

- -******* - -

- - -

- -### 作者微博: [@GcsSloop](http://weibo.com/GcsSloop) - - diff --git a/GankDevelopmentNote/chapter_1.md b/GankDevelopmentNote/chapter_1.md deleted file mode 100644 index f68e6726..00000000 --- a/GankDevelopmentNote/chapter_1.md +++ /dev/null @@ -1,65 +0,0 @@ -# Gank开发日志 - 整体规划 - -## 前言 - - 一直想找一个免费好用的网络接口做一个完完整整的客户端,然而一直没有找到合适的,直到某天看到代码家干货集中营的开放API,感觉很符合本人口味,于是决定做一个Gank的客户端。 - - 然而定睛一看,Gank已经有这么多客户端了,而且大部分都做的还不错,让我也是压力山大啊,个人觉得,既然要做,就肯定要做一个和别人不一样的,有特色的,这才有意思嘛,然而带收藏的,纯妹子的,日报型的都有了,思来想去,也没有找到和别人不同的突破点,于是就暂时搁置了,突然某天灵光乍现,作品要体现自己的特色,**自己的特色不就是懒么?所以就做一个最偷工减料的客户端吧**。 - -### 先预览完成效果,大家猜一下最终用了多少行代码:bangbang: - - - - -**嘻嘻,这个大家先慢慢猜,稍后再告诉大家结果,下面开始本篇正文,对项目进行整体规划。** - -## 一.需求分析 - - 在做项目之前,肯定要首先分析一下都需要哪些功能,以免花费大量精力结果实现了一些并没有什么卵用的功能。 - -### 基本功能 - -序号 | 功能 -:---:|-------------- - 1 | 展示最新的干货信息 - 2 | **看妹子,看妹子,看妹子!** - 3 | **保存妹子图片,保存妹子图片,保存妹子图片!** - 4 | 查看文章详情 - 5 | 可以方便的分享收藏文章 - - -### 可以砍掉功能 - - - -我们百万大哥曾说过,**要么砍需求,要么砍需求方**,由于本次需求是我自己提出来了,砍自己容易被当成精神病,所以我决定砍需求。 - -> **接下来请欣赏我如何为自己的偷懒找理由。** - -序号 | 需求 | 理由 -:---:|-----------------------|---------------- - 1 | 展示最新干货信息 | (必备功能,保留) - 2 | ~~看妹子~~ | (看妹子还要新建显示图片的界面,太麻烦,砍了) 喂喂喂,话说这才是核心功能吧:joy:怎能说砍就砍。(那就交给浏览器干吧) - 3 | ~~保存妹子~~ | (既然看妹子都交给浏览器干了,那保存妹子自然也是浏览器的活) - 4 | ~~查看文章详情~~ |(什么?你说要做一个内置的浏览器(WebView)用来看文章?,话说一旦做了内置浏览器,就需要提供分享功能,提供查看保存妹子功能等等......这么繁重的活怎么能自己干,果断抛出去,拜拜啦,万恶的内置浏览器。) - 5 | ~~方便的分享保存文章~~ | (话说这活不是已经交给其他浏览器干了么?) - -**砍需求成功,最终只剩一个需求了,哇哈哈哈哈哈哈~~~~~~~~** - -话说这样砍需求会不会影响体验效果?接下来分析一下使用外置浏览器的好处。 - -序号 | 优点 -:---:|--------- - 1 | 手机默认都有浏览器,所以满足基本需求应该不成问题。 - 2 | 防止内置浏览器(WebView)因兼容性问题导致阅读效果不佳。 - 3 | 如果使用Chrome浏览器,360浏览器等并登陆账号,可以方便将手机收藏同步到电脑,毕竟大部分技术文章在手机端查看效果并不是很好。个人推荐使用Chrome,用Google账号登陆,在文末会提供科学上网软件。 - 4 | 作为本应用和核心功能,看妹子,保存妹子,浏览器都可以很好的完成,甚至你可以在浏览器中搜索图片出处,高清大图以及类似图片(首先,你要有一个Chrome和科学上网软件) 效果见下:point_down: - - - - - - - - - diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 8f71f43f..00000000 --- a/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/QuickChart/Bezier.md b/QuickChart/Bezier.md deleted file mode 100644 index e4adf995..00000000 --- a/QuickChart/Bezier.md +++ /dev/null @@ -1,12 +0,0 @@ -# 贝塞尔曲线常用操作速查表 - -> ### 贝塞尔曲线的操作方法均包含在Path中,详情可参考[Path之贝塞尔曲线](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B6%5DPath_Bessel.md) - -> **表格中演示动画均来自维基百科** - -贝塞尔曲线 | 对应的方法 | 演示动画 -:-----------------------:|------------|------------------------------------------------------------------------------ - 一阶曲线
(线性曲线) | lineTo | ![](https://upload.wikimedia.org/wikipedia/commons/0/00/B%C3%A9zier_1_big.gif) - 二阶曲线 | quadTo | ![](https://upload.wikimedia.org/wikipedia/commons/3/3d/B%C3%A9zier_2_big.gif) -三阶曲线 | cubicTo | ![](https://upload.wikimedia.org/wikipedia/commons/d/db/B%C3%A9zier_3_big.gif) -四阶曲线 | 无 | ![](https://upload.wikimedia.org/wikipedia/commons/a/a4/B%C3%A9zier_4_big.gif) diff --git a/QuickChart/Canvas.md b/QuickChart/Canvas.md deleted file mode 100644 index 709e5b96..00000000 --- a/QuickChart/Canvas.md +++ /dev/null @@ -1,14 +0,0 @@ -# Canvas常用操作速查表 - -操作分类 | 相关API | 备注 ----------|---------|-------------- -绘制颜色 | drawColor, drawRGB, drawARGB | 使用单一颜色填充整个画布
**相关链接:**
[【基础-颜色】](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Base/%5B3%5DColor.md)
[【Canvas-颜色与基本形状】](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B2%5DCanvas_BasicGraphics.md) -绘制基本形状 | drawPoint, drawPoints, drawLine, drawLines, drawRect, drawRoundRect, drawOval, drawCircle, drawArc | 依次为 点、线、矩形、圆角矩形、椭圆、圆、圆弧
**相关链接 :**
[【Canvas-颜色与基本形状】](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B2%5DCanvas_BasicGraphics.md) -绘制图片 | drawBitmap, drawPicture | 绘制位图和图片
**相关链接:**
[【Canvas-图片文字】](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B4%5DCanvas_PictureText.md) -绘制文本 | drawText, drawPosText, drawTextOnPath | 依次为 绘制文字、绘制文字时指定每个文字位置、根据路径绘制文字
**相关链接:**
[【Canvas-图片文字】](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B4%5DCanvas_PictureText.md) -绘制路径 | drawPath | 绘制路径,绘制贝塞尔曲线时也需要用到该函数
**相关链接:**
[【Path-基本操作】](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B5%5DPath_Basic.md)
[【Path-贝塞尔曲线】](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B6%5DPath_Bezier.md)
[【Path-完结篇(伪)】](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B7%5DPath_Over.md) -顶点操作 | drawVertices, drawBitmapMesh | 通过对顶点操作可以使图像形变,drawVertices直接对画布作用、 drawBitmapMesh只对绘制的Bitmap作用 -画布剪裁 | clipPath, clipRect | 设置画布的显示区域 -画布快照 | save, restore, saveLayerXxx, restoreToCount, getSaveCount | 依次为 保存当前状态、 回滚到上一次保存的状态、 保存图层状态、 会滚到指定状态、 获取保存次数
**相关链接:**
[【Canvas-画布操作】](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B3%5DCanvas_Convert.md) -画布变换 | translate, scale, rotate, skew | 依次为 位移、缩放、 旋转、倾斜
**相关链接:**
[【基础-坐标系】](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Base/%5B1%5DCoordinateSystem.md)
[【基础-角度弧度】](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Base/%5B2%5DAngleAndRadian.md)
[【Canvas-画布操作】](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B3%5DCanvas_Convert.md) -Matrix(矩阵) | getMatrix, setMatrix, concat | 实际画布的位移,缩放等操作的都是图像矩阵Matrix,只不过Matrix比较难以理解和使用,故封装了一些常用的方法。 diff --git a/QuickChart/Matrix.md b/QuickChart/Matrix.md deleted file mode 100644 index 01bf7cb8..00000000 --- a/QuickChart/Matrix.md +++ /dev/null @@ -1 +0,0 @@ -# Matrix常用操作速查表 diff --git a/QuickChart/Path.md b/QuickChart/Path.md deleted file mode 100644 index 6ed41739..00000000 --- a/QuickChart/Path.md +++ /dev/null @@ -1,31 +0,0 @@ -# Path常用操作速查表 - -> 为了兼容性(_偷懒_) 本表格中去除了在API21(即安卓版本5.0)以上才添加的方法。忍不住吐槽一下,为啥看起来有些顺手就能写的重载方法要等到API21才添加上啊。宝宝此刻内心也是崩溃的。 - -作用 | 相关方法 | 备注 -----------------|-----------------|------------------------------------------ -移动起点 | moveTo | 移动下一次操作的起点位置 -设置终点 | setLastPoint | 重置当前path中最后一个点位置,如果在绘制之前调用,效果和moveTo相同 -连接直线 | lineTo | 添加上一个点到当前点之间的直线到Path -闭合路径 | close | 连接第一个点连接到最后一个点,形成一个闭合区域 -添加内容 | addRect, addRoundRect, addOval, addCircle, addPath, addArc, arcTo | 添加(矩形, 圆角矩形, 椭圆, 圆, 路径, 圆弧) 到当前Path (注意addArc和arcTo的区别) -是否为空 | isEmpty | 判断Path是否为空 -是否为矩形 | isRect | 判断path是否是一个矩形 -替换路径 | set | 用新的路径替换到当前路径所有内容 -偏移路径 | offset | 对当前路径之前的操作进行偏移(不会影响之后的操作) -贝塞尔曲线 | quadTo, cubicTo | 分别为二次和三次贝塞尔曲线的方法 -rXxx方法 | rMoveTo, rLineTo, rQuadTo, rCubicTo | **不带r的方法是基于原点的坐标系(偏移量), rXxx方法是基于当前点坐标系(偏移量)** -填充模式 | setFillType, getFillType, isInverseFillType, toggleInverseFillType | 设置,获取,判断和切换填充模式 -提示方法 | incReserve | 提示Path还有多少个点等待加入**(这个方法貌似会让Path优化存储结构)** -布尔操作(API19) | op | 对两个Path进行布尔运算(即取交集、并集等操作) -计算边界 | computeBounds | 计算Path的边界 -重置路径 | reset, rewind | 清除Path中的内容
**reset不保留内部数据结构,但会保留FillType.**
**rewind会保留内部的数据结构,但不保留FillType** -矩阵操作 | transform | 矩阵变换 - -## 相关文章 - -* [Path基本操作](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B5%5DPath_Basic.md) -* [贝塞尔曲线](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B6%5DPath_Bezier.md) -* [Path完结篇(伪)](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B7%5DPath_Over.md) -* [Path玩出花样](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B8%5DPath_Play.md) - diff --git a/QuickChart/README.md b/QuickChart/README.md deleted file mode 100644 index 77d6afb4..00000000 --- a/QuickChart/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# 速查表 - -序号 | 内容 -:---:|--------------- - 01 | [Canvas常用操作速查表](https://github.com/GcsSloop/AndroidNote/blob/master/QuickChart/Canvas.md) - 02 | [Path常用操作速查表](https://github.com/GcsSloop/AndroidNote/blob/master/QuickChart/Path.md) - 03 | [贝塞尔曲线常用操作速查表](https://github.com/GcsSloop/AndroidNote/blob/master/QuickChart/Bezier.md) diff --git a/README.md b/README.md index 4c354d0d..aeebdd41 100644 --- a/README.md +++ b/README.md @@ -1,53 +1,6 @@ -# AndroidNote -### 作者微博: [@GcsSloop](http://weibo.com/GcsSloop) +# 魔法世界 -我的安卓学习笔记,记录学习过程中遇到的问题,以及我发布的安卓相关文章。 - -如果出现链接失效等情况可以提交Issues提醒我修改相关内容。 - -> #### PS:点击分类标题可以查看该分类的详细信息。 - -## [自定义View系列](https://github.com/GcsSloop/AndroidNote/tree/master/CustomView) - - 序号 | 内容 -:----:|--------- - 01 | [安卓自定义View基础 - 坐标系](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Base/%5B1%5DCoordinateSystem.md) - 02 | [安卓自定义View基础 - 角度弧度](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Base/%5B2%5DAngleAndRadian.md) - 03 | [安卓自定义View基础 - 颜色](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Base/%5B3%5DColor.md) - 04 | [安卓自定义View进阶 - 分类和流程](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B1%5DCustomViewProcess.md) - 05 | [安卓自定义View进阶 - 绘制基本图形](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B2%5DCanvas_BasicGraphics.md) - 06 | [安卓自定义View进阶 - 画布操作](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B3%5DCanvas_Convert.md) - 07 | [安卓自定义View进阶 - 图片文字](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B4%5DCanvas_PictureText.md) - 08 | [安卓自定义View进阶 - Path基本操作](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B5%5DPath_Basic.md) - 09 | [安卓自定义View进阶 - 贝塞尔曲线](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B6%5DPath_Bezier.md) - 10 | [安卓自定义View进阶 - Path完结篇(伪)](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B7%5DPath_Over.md) - 11 | [安卓自定义View进阶 - Path玩出花样](https://github.com/GcsSloop/AndroidNote/blob/master/CustomView/Advance/%5B8%5DPath_Play.md) - - -****** - -## [教程类](https://github.com/GcsSloop/AndroidNote/tree/master/Course) - -序号 | 内容 -:---:|-------- - 01 | [在AndroidStudio中使用PlantUML](https://github.com/GcsSloop/AndroidNote/blob/master/Course/HowToUsePlantUMLInAS.md) - 02 | [优雅的发布Android开源库(论JitPack的优越性)](https://github.com/GcsSloop/AndroidNote/blob/master/Course/ReleaseLibraryByJitPack.md) - -****** - -## [速查表](https://github.com/GcsSloop/AndroidNote/tree/master/QuickChart) - -序号 | 内容 -:---:|--------------- - 01 | [Canvas常用操作速查表](https://github.com/GcsSloop/AndroidNote/blob/master/QuickChart/Canvas.md) - 02 | [Path常用操作速查表](https://github.com/GcsSloop/AndroidNote/blob/master/QuickChart/Path.md) - 03 | [贝塞尔曲线常用操作速查表](https://github.com/GcsSloop/AndroidNote/blob/master/QuickChart/Bezier.md) - -## [混沌水晶](https://github.com/GcsSloop/AndroidNote/tree/master/ChaosCrystal) - -序号 | 内容 -:---:|--------------- - 01 | [在线查看Android API源码](https://github.com/GcsSloop/AndroidNote/blob/master/ChaosCrystal/HowToViewAPISourceOnline.md) +欢迎来到魔法世界。 ## About Me From c4a946a22204190d1184fa413009852e4446e831 Mon Sep 17 00:00:00 2001 From: sloop Date: Mon, 18 Jul 2016 02:27:14 +0800 Subject: [PATCH 02/61] =?UTF-8?q?=E9=AD=94=E6=B3=95-=E4=B8=87=E7=89=A9?= =?UTF-8?q?=E5=88=9B=E7=94=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MagicElements/SpiritForest.png | Bin 0 -> 828618 bytes README.md | 10 ++++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 MagicElements/SpiritForest.png diff --git a/MagicElements/SpiritForest.png b/MagicElements/SpiritForest.png new file mode 100644 index 0000000000000000000000000000000000000000..311f80040323ecbba5066da8b45b3f581c4fd0d1 GIT binary patch literal 828618 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

L1R!BRvQlEj0U)L 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 x2c8$UIoCTVPn)meO5 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%0DRS6Q^INC5i?MHCxFw? z<5`s`GmBg|d};u3o6|>!X*wIM!;fP-%16r!c&klT4#UAlo#oE+%GPA&C)nLY> zu1BJZ3eHco7K9PjKz>h#YXNb>xL7Nb6%7wo4OyFjHYbk{0ry2C>?x4iEb^Fl2kugs zLapZ{l@WxhEbG`LA>DfIB_74t5?D$6Ywb)WJlN)507a2xPIUoU^!apq9NXc(iXvRx z!fC9~iy3-1yv%JQqype8TH1&%@rMDtH7KBEBmoq(72b$JTt$xxfE9Tqde*|0sH&|o z6o~f4%*Nvm#KU0(@6*-=o&@ zw>Q82?QcGM{D?boET?nTx)Bfr*~bU!_9ykz$Mw? z7w5HtIF(u6<-wMyA&X74zb;#x-EW)2+Dw~z37<~#nB|8}{oGo3%av`QAU#ETzi@gP z2qXx{;Xp#a5c_mT1il`50(OPFo?^`qN^?vR2tK4CT-CGuWEyyM(DSFW8GPz6jPi6z zONfeoX-o7|YDLrP%~!f&M9&u!Zv0*+utC)%k!q@dXYYUgN^SIM%cS&p2QN`VKm6?R z;>p9K-3|YpuU$GX>uQlL$`tlX?UALg6H#Y4{sd*I3IPX-683j#N+^gbz>^tUX4S+j z(yU(0s_KQDKeN-rCYd&9Std-~)B~><3cuof9m>&glF~|Qk89EBD5(V0oWJ$uoxk<% zOKO{oSKE)Coqzu?4mY~uU;g2Xy}fvIJu1%Yjb3zmC;x;0`T6}jG#Yi?A!&VIbh@5X zb#%$bJ;phoDZcoxe&_XhSp3QV^E~Lw%eVUBP==^KPUp)SR$+42Jo>&`bcb&=JuRN`O;$NXZ`g}4ebdoeO-~kjZwZ&;CD&TnT^!!EHOq@k3jsy~eG+tu&*4H8# zr)knb$v^S*=@N>f$)dpSP8R@v+r!BwoMRq%15v!h>(@!ML)04bJ;WIy146u{cr?pW zD75peRD}9*Fdh$vqn;=Dc-*^kd1rrrONNlz73ANtsNn-c*g*$WH%6MPY}qWbCP&pO zR9699<2i3t$T&<$3ZPmc8@;WJDbR8WWn_gD30A~;?jd;+PP1;@gyD)phFvTtx8j85 zxOQT)&bsD;qu$b$%z~Q{C5~J!kcjW4BWY6(&I*$b`h|}YPQ{Yd z$QPbT?m`b+87*1lm)aHe#arQaywySjASbNuxVz4J9`6tUonw}T{a~HQF{;+!G`Az? zI6j-Y&EpjJ0p5> z{mRd7tnb!Mp3KhjG;7LAw{;M80AbUz>;{{{_p^MWvV3P}2s@y_d5m_EB2i{2b&`QQrTrxLW;O@gwnugO+2YuDy zYmvY=+ZfA@*dnB1M$_~(gV?*ViKS#()f&f(;HZg}_Q3a?_btGYUpASsf~WSXW(*p@{Cg8e~Q z1`HVXkNqRS{?dnGzy@rxZn%$NIu&t!$dK&z1ZaQsQ3*HuLt9l{Q#)5PN|e^48k>?B z4&HOBG?0^>5TvIKh@^y0Exc5z8muLgr>COUgi;LMlhZx&L7C#tmQHujpY(mUb62;{ zH;UppL@3ZjrHTbPJLHhPiWqVhGH-D}F@XzYysWw-tM{9XLtGbbndh*oTM<>f!Y##l=XA>{#`GJ(IQE0u< zPLA>bZozRdFRCm_YN@Xb!lt!#Wpjc7&UC2tJm;(ec1SizyFgs5%K$DK5G-hGpi zhE3BHjSQm@aL)I$ETiB@C_kh!5-KN{8O2Izs1PC$;?wL*L4ym&saB}Lt_k8x>t;QYh--)|B>Mbk+L8oB^WK0jjs})!f zte2n#TQ;1q>9%HBEcW(s@`y%k!)mI^?m!bJ3K&}p|C~Shly4t$FXQonxb}_i$}vp$ zW@{!(LS4>nE9kas7S34G^V(yvh&v+@=v56d6LaDPcWrmGyBL{I|23h)aCD`*@p}CF zEphkvyII{egDBmjlKcF-pFQ}4f8`GY1}}Oq>j#q|rL(qad|hXgD|-ZrHm6`6`wWtf z))S`IFyZzHUC{>cLZ_6>{b*CF%aglNTKD!7LVHf32Z~og%x355@Wof-*w+$fVov`6 zO=eSAx*aeQ=NsRNKZ-b1w1a`I4gG*V0d2T2#(V`OV|V0-0=$1VX5Y33PN5ynA}L{M!|JN+ zqQVak(xb5q!3{T7d(W4O$DJ}ZdTO3#nF$6lqFaDdB|{lvYw^M35R=tqg{L$Ol1VCt z;r0g$dSZ29XirD|6!ff(YUpG7sXpIU549Nhrmg+$`D-r*_fN``W||&fH_a(j-XgmE z2Ge&Pe=hUZiY!QMXb;o;X5Ocj9pWqtErLyLPcAphRSj952)?bblae-yeVDiqf}j`f z1pHVas;2zx{yn$nKn?(Rcc*_1Mvi#zTdp)i@r%wJa=PUr?M@z7{zU9w7sFhjdH8u{ z_xxtdbqSeGS-UZ}OVuuSo&1hfa`R!UPkrA&U1K+JjGPd#9huIJmG6YBA=rSX1b(7@ zAw&$$3^$p3@(|f`Ue$s^&30Y*ZQJjqlroo#67NAUy4Scj*q&`8o2^n=OY_G5G)w}S z`_tigTWrLf)eG)V2sxEvwz>AgXg>@-C>pAEEO*UF+sSp^R&qMY(>Sc_?zJ!6e*IUz z^83H{r|;jr-+3uTPs$e}VT-iux9y?Ob*GmE4}ws|o6cB}KPYS9IIb04(j~SH6vbLJ zv}Mq@aoH6`SL&2jCl`i_ILb}5frHBi1KDpJ<^Rdgeev)O?=LpbzI$?UwaUN#*8T@M z*qM`qXn&Bc=hc?B(|7CUmGm(!{Fv*ygq<+5_Q`Eu42!?!}vkKRXYV+Uy##e8@ zoc*u=M9UTY3ums@}anE0bZr>gs-)9o71qzy9L^m!H)4?|m>? zEamm1k=H`rIPyKJ5iW{mtId;*Dm2=1mA3RJ#&$Ob$?g4ps#%c z@AVGSsb#7k_g7}FO=G<_@Ek#;Ga=*isyrzkH)TVC-;2)OouuB{b3TsVi3l2 z#Wov5K*|~sQZ7kZEh&&vI&#Rkb8^8Dj-pZ%!5^yIK_}1^bnrPugP@xk6Pq@r%XhZE z;<7A*1-7V1e93p2E~x0 zoJdH`l;o{qp;L3(>aH#rZQ5Qe6u7*WP={VKs))5`>O$m!htq0!f*R1Wz%Ff{TOD#I zx*S)Vr`3GX;hf-);7qcgW<9DLo+Yi?dWpy@4syoM&hN5SeOT|^b7v8u! ziFz3=IKp7MZR@(Z|9JJ}!oAXsp?J{pAdI^R<8*%1r?nZ6#kE#Z5O3>pL*VZG{>QS^ z!=szM_R6YwAXPDn4>=E)+ml`tdzxYvp$S5i2JeR!XB39`)MK&Jrqpl4|Q$s>#I0cH!ZEG#u#jnOR+mG*t7--^e_V zGC#}N8`+ecZnptQ(+Q{jL z5jU4dLSo0^RPyeR@_3 zrc1V~P{g*|rWy|Owl#-`sdESe79f;Pp@qslg40HqXspn4*L4#45dZ679^a+Rc^jcM zNQlQ7j6xiVUJFGPD;&b>V7G*aj9-JsyYD7z6kWLmMGpnNg-;%HJYBxCqmmU^6|M;a zgC4QFsGX?okBIK=F0P0jw~H=;7CBh*(!vk5Q_d+9(~)9l_#&KPQ@4whEiF>8V(d;Q zS%}>T5vbw#E-!!UrKd2NHq3W6Ce)e|o{FKR2`@p>vam9B-)8^H%% zJH_efFrn4#Z3{;5zo|sGf=LAC6yy*8!M|RA{<)Wd2RfXlH?Ai~Q_rY4>|H&&ei%o- z+UokE?l!tLot9V#R4Rq=H4HImMk_APn##-`J>FcN8A*!Pzf;vyUTa^fTyxO$(;VPJfKnQ4Iqrj7UOOKO($p8>P39uYuyF`-_U= z<;VBK)Qe&$^qATl z6wVr~3rxUStXZ6mdYNp8l)8Ly-wAUBaE;SAByu8bAenX{W`_tVQ*DlFW2MZ>()C1R zLMRM0{Yz*ygp*K2P|@0+Z1!`$TA58e9A3}q)z`G_YA+dvHuCEWrJJ~Zc7CHTjWQ34 zesFjlN*H3v5-0YHj2=5kfGbG-=%qNno~2fJ8`UMkOK`f%K0mEKJ1ORuROWTGw^0Un zj6fDuDQ+sw_1d^Y;R3A}W7J~3q`UThbi}_qg5SLnfM^fA2n-(u?CP5$8?)`DSU={~ zjKzI1IHaGO^{hk8BHWY;b=j3?jh3ChY@jCQPL|qIw=1d&W7;DDrUF2IaQhb9s@;vA zFz8P^*=QXSbOUW#;Mi9{eZuY55E-Op^nA7#>v~lt0Z)4g3p@ie90~=orEJo5f$*hj zn$0$gdZOifgX9}u?N_Mp;ao)5(N=;-G8{6!&ELA7R=sv^Sd<8;HaP_W3PbzDXpn}r zYV$mpU7GzjZhhhH{f~e63FV+bQ_7T~&_RC`z!rNpG3#6Z;CF`@KA62%g%>Y%}m#;hVH)qjXTG``1Q#vuY2Cj_Wkwa2N$c*^MCH^ zFFk#{>;lTXOnTUkMppf#@@6i zqRhQ=Zy1FGTJln9jVW-${dOFVhUc#eGv;BplYd2-V;5)5N6M=<%|!t{R4c+DANC2B z0mfpQ#0H*Ut4ap|LkXw7&k9|pkd6=5>zYzBK@<%ROxvt5_PXEOqf(t}xLz9V@8@|= zV7!4GcGX-gD~c7+g$#qqI1JFg?3xyS6gyS!o%c52wZ&`}0TaCei&HqSK1)^Fl7fhZ zDvfIkI9GVD)t#WSy^Y!w_<>_?)$=P~!wlGTC%F*USp6cZ6b(rk*KgX{_xy<5>CR8U zS$EwcFbb`k$FgpM)J>7Y5`;UOB;P3+<4j(o&UdPj&l8>>ba74qow1t9B}dDgikCHO zmTg&4Uf_gv2ya0kq-Lh%^a;Az(P_GbvwFjdMr3(7-9s3x%eE{jud!O;(KugDh$rKK zPQz2jg-LXLG4Q8{uYOg_&GO;*1872byQYVtY^ROX&BNt-QEo?j^3IDa&op6*&Aj>c zx1XFs8^}C4t1dU?$+PupS_^B z_xoND(4RN-oR!m}HddX^&0@3TO6}&B-~fda)pn=ui3y7cDs6)HaDcA7Gg<)%rgTXq z5%Oc;?f73fl~v&GQx=9ZpAY?P=Pd?L6)#3HoBQIhPsLq3UqO(KqeUUQ-3WXOjukDy z=>X_R0i`h`@fe{h(Cut5pZoLdR9I>?YuEkKto+(DP!&2P6{I3)%jM*(zUKpn1oi)jMoM;NN4816Jh z=w1T|t0%FNZy2FxhdCytmN@68uThZvrX7T()D99q@uCgkuPy*O zMBbwhFI6C^=zaZq_Sxg2-zM}r%7|57)Je~&M$*gnE+5mT;Z9?og$Y|eZO=Y4=W|FV z2Uq-dMX2dhWHF{eFvZMAG76JQiTc=Y&+@?r~Tey?Nq;_NMdTG^ZgKf z7Ny~H?Lkq4${I)lwXR$Q1BPB#82F(xaHB^+AFP_HqMFBOMu8s$1mh?V=o&!O4inYT z*J#(|gr5XhQW$>qiB;=w)2{#nm+8bN$G3etX% z^eE`@Y9X$^{_^YJd|`3EI{*A)eFj$sM=EubzcF5b3!`XD!Z{tI@ILy!J|sd~D4-HZ zz<+@0i>ld{bhYzOPdZ(NNl2)jPRlwB4?hcL7wv_XQS}%j~k=M&`Ot5RV zW11Y|%iQf=kYg157a$#^q-HWq2GEt%=W&u&7TTXd=mkkawLuU^9r9tj^A?M`#!p+3 zg>7TZ+}Je)?6G$T5q(y3u6P|;49jY@lk~uv|e(%>4sARAQaQW z&9ma=d~xS`{FnEc%C6ufkg{@wDvKg+>?ahxdm=aplBpLT1mP&~%gRt<3$iHS-o?DR z`*3|ZtF=T09OcmH@ggBB94bW7&Ns}p;&{6&J$A-sv?3|n_^mrO-;shGdM7kP;lwFj zP(9pTf0O@>|13GU#rQxh=UqK-A-pO~QFP&6AaAKaSL}>KXyyS`gG;7*jb!ZTe-e0sKTb=G4H_y2orS< zF)=TWdqavZ+gj3I7?1O^DXYyU594}aE7g7BTKMqpSy8Ge4cx?kRh4ojX*1NXjz==$ zrtf2F1tJHu+M{$xdABu{?vF!N7Fi~*?u%>v!7qLF_FkIM+nmX@tQ&6=ZqZJ4nh;1{ zs;44)ypk!O(ut4N<=a5E1nt7H&xbzJBK==AT`j%JO71uQH21%JJpRvr+>^iYAN_2pAADPWeEzr?_v0G}qjgb7X&6F{H==hJ3O0)T!#un; zP6)WyW@mHL9`(av#_C4(lL4WH3%LNrONl(&7k=7QYud_HU7^>WhgX+(qUL~wu1(`; zq!f_0_Px8ad$UbV#UB8G(-MGJlX3dwNW<2#fG91f9&Jn>ZuPc7Hwpxy`EuK$tBZrZ z(92o^JXPIGvOJC#n{^V$I1}|GW!I-?<>h%@ql=+iXTuB`TN8%dlP&EBl*h^?ey9Sq z*ySce%Tm=G{Md-w1_BO@qMwhx9_E^u8%IT_4Un%(of#^D3LfJGB|d3uQa8T6bgxIxT1&#!bUQYmPf<)#r-u zy1?YSb6Q2PVI}jDPTlHG*4%r>yo&Rh%QgOP6tKj{4Z`SAv8NYamhzj2EcLs^(l&U! zJ7zt7kkv@_)*XKvX_U0PTHj?K)cm~{zo-_E7mG(G46r?*`-%Tjp)u+OS0>%nfjm5@ zy`J{6uw1tFxw@JsRN38sv_1J~UItW>nNJ_D;*@}^KDn$e=2dYi+lrP$8wa}BbQ|lB zjwY|Y_|EmKUzi@bn_^VPCiZp!0u^tJ2X7^i)72dMC-b)h;R`&w+YoJcPe4X)hU- zcD*jwje&q?N-Vf$@>~r-io!7@*1lx|I)SW7v4<%{vSTsvQ)R; zGn!@zEZl7xP|s9LYogQtnsc9hZ+1rKGEwdX)K#NUed5kA6~mDN)L8@BBv9r&szp3zBPVM{k0tZFUJz{Q--BobiJn1% zU^PR4P@o!7O-Hd%V5++xdx_|_1gWCH7u{~A9TM*`ALY^h6+gUAS1kw*Y%pZ!M`+Eq zE<-}@o!(juLLJ&+i)Zd2IxGFWZYd2FHftcZc9>#FQmIb0Cdeb&8hJnMWfXyJu{F9B z{UMbY{&Hq?(?Qvh!M=`gQnhJ9r~?O$wk4*3{kk@nm+R$*vL7Y{!Z@fPb&8{hgYkHn z_s%cRB&^fI6n+}kG#ax5v`D3P@31ul#GMBmtrs`P>bdh79H>J4QR!EH>}y~CYrjr0 z>Fmh^Kcd``24O6`T^CY7W?cjjsaaMXsBUmVoEhzmbmXOFt`cl`RITZI?RR){DFQYRuF`LIfYhNE#NY>+j>d56OBF5!4xqkRK4GfJv{uzYmZEEaJN3COI+ zw=>22huPi;93f{_0=5W_k%N|b<%0))lBBm^@IZ9)oq&p~^y|hQ?(lY(1U*6Z0|ee$ zg;pJ>`Z|$~90qIU^>;iDj<(JPRR;}YFL(P-Lyrp zn`34b#OBaN!Q*LYiBT;ic;Bj&88{lQ7EOy5Rhn#{eeET2|IB>09;Smljct;$B&M~+ zhhhJA)VmhOV;&@(hsqlR3F5)oveAZHasGIHeou zp&oE_-F8RC+qERz5q#^suAB*`Gr}^?3b1t=<`DR?S8fL#9KJ0rvE|HbmX!T%G=Qa_ zsXI&ItVZ|EB6_ji8Gh%+qg31W6gb@Y$0d>71m`gw3IzFUA;Bt1sfn?0))Rt@c zr5E}oRr`J$`oa2w3Ro)P>v>(5XYn^*I#8pqqS#qzSPCR881}1L>TMb4VtPIE2z>|U z<~y$h{o|uRy?S$W{b(}S6EEK$Z7@Xb^pQH2wEpe)+e4^37j(Yya)n_a5lw|MZ97^TTx9Pr{yeI;(CR52^0@ z(|`L+^w{7q2nT}AyZ_<8c>kaOmLB@Khl3D1|I*i9e(h%dXVv#t zTFSY~dddDl-zZH@skLh7b0EA8k(lrZ4?T`M=9&RXBsFhPZ=uowDKhO^s7nbk@c%cf)|ocjI% zd~hnyLRiA#OcXARs-$}cE`rXKzbP3HWH0_4?^@D8<^_nhDnNelEd2*YA@V}I$1X>x_T!3Id7;6 z-|#H$=wc|1MS;US2J@-2x!A0r6e%n(HmoT%EyvFFEgYk)gFaV>Ee|rKs|y@Q3vmP_ zca>j#p*(wFwr7sJ4385CKExn&^~On_QChTTr|RLt_9yw1v*HIIEgn5yKbtocF|sR3 zrEH!A(}U#k$>#g-KK<;|`Sz^QwZ+rM=sGLPj^f78eB;+|9>1eBTW=O&m{6V`^n!c$ zzw7a6GQ3W2YF$2|ms`|D93}h1EA&_hT%>My+W3wt+jL^ghL z`pPiM9?c&$wM^mN(GB){TW_;k6_s3V-LkGkOO-CKSj)fl*8VWF-#MLKoSU?lHb&IIzHH6l=p(^hX%R;AkZ_iq z7rbhMZK+QeZJLVxJ}Bw4tt~15Q|JQuunB9OS1qRX=*1X9OAsocFiWLUP9-b05ONaE zzMaalK{q-)m_%2mXvxQ+W2`x3-B~zWyBZ6#P);hF)2%hS1tAJeurv{Qk9D!AHFq@4 zHs;E2k;=7&wD2IM70GJp!R*U;&#f?@7n*!0jzGJg&|2t&0n#*~J9D)G1f87M4&+xs zTHhbGw1nV364MgG85XTdr95eTq~#Q=8!C;I!0D#cuIX;vfHb8aTAIECnP~1oFaxI% zM)+_k=JYYVsVQz4o@Mla*wFx*^jQ=v4M8HbKMSZ!bV}GmwBf^3>Fg6Ysv_Z}C8$&TW%7whBiNPA zU5hS~$wSDwGs2Idr;Lat`QmsY~bM75hO-pn%|D>t5UP#*>>7(0; z!qDq#G(|t=g_fd|1MVE~KXm5x#_?gC6u|SrLKpp*j=!~T=U<2>-PQa;_u1ua&{y(^EQZE z*WT|`B{Zl5f~{IU(aV(*B_Q>w~LO~LkFmrT0pmwBQGR|8udtRFw?O6!}jqpCIu zS#^s^TI2WI_yp%3pld3=8L@8VC4E7~Oz3ru;$96gZIQte%yV|Y5pT!BYh~9o^4Thk zboFd&oJj?30BAs$zm0wm2DIA+<>Z7(3uZ3JFdiR@b__sfY*oZjA1lrCDFpwi~?i^LGwknbwtZ3aM0So5R-H|yo7Xb`fMlonCF!6X$Pv8ZwVI4sWA&3qXVNJ)9pL-8kV)}M@_ zKLOV)N-i$ZVM;u(ZONP}QFC#g9bdsAFKuJ#pkxqqo?}wE?gT_yg!bUaO69C?Wi3Dp z9z8vMkc^&+^h#=qVWewmmojYqK4ryGNVS`s>pj}J1X9`7`fy_a->>bITvx(|P8tHM zj=qG#T{P}<4JR6Upj;idJaL!1J2Omd6{xCwb==S|zWcoH;M`o(AViTdabupfpZ;8aM7Ry z4c{1N>e9Img`>A4AyeFIjRN6d=hCux+Wp@DR(|E*!4&=L$KKvAv5!B&p*rP#G?*#w zVag9^$;&;n!R!>IuAGcK$Y$>N+}*OU9XR$Nr35UDKwx(ip0*X3A#&G1&`t?VKeBSw zpzj%{@!?)fH4jd>AP`F#VwW!If7-HwBLgPz#6UzghwvDI)cw4-I$O7C7KGuWGtZ0F zSKb~hSN1zUsI7(pNn56IZ~ejgr1+=hfABLegh%38AegSbDiNyn#XXn zfE(I-|77+DfB#~3nT`$yhBB3JStY!_9V7y_LVhwNOzGg63JTqBN*tfF@4mPEsoPOM z@X9bgm=2!Ji)yBqp`n^^dFr3N?+?;UBybN)Sn<;9$6tT##-DG#zfSe($LsA}zVVge zvavB011+r|uXAVStW9X)Qo5TLB`v&B8u%X6T`5}jLrmH&*K%(V?Zv|l&SjjMywU{j zN25N5F~T-o^@Z}F17UaPWnA}89-41IU9J^{fk5bWN%$pAWAv%e!a@yC|41b~C8Bjv z;-4{K=^qpFh@x#-v;|HyDTBjR!*Snw1Qz!PR4vo`104dHmJ&k?G~`Dm9MReqv)_&tKNzdfsJ@}Rb*G&`c&IRse=_GSW z#Z$RGr}81oSVAuYHm*CvEf}X4MwW%jkNjvDtk&gaQA%Gf30Exb)mMfx@zh+MK3>P? z{_>RZIOM98c~1*`q;nKI-oUt z)Q7{=#gf$x^!Juqkp^CtwN8THQA_BhMb}??d473bRV9X;;s9jt3W_ZdOJF=m!!{by z&NFp|=CG8u!dDXjY6Hs1-EN%;$bDGbXpoO3x}(g8|AZ zqSOuaI1DZEMHXj8XoQz17Tog|R(poaMu(GRY3yZL_Ogg~5dlo9-S(1vWj1TC@(AB= z0Ffo?Cn``iC=l+zB!H7MZ;<2%8{4wT3!?5`@>G-C!|?^CL~j?zxPN`@tQWxV6M}LwmwDyo4Gq z#VfM3oK z2S-z?hTY7RbM+uhIFLN+b1!EFz$NDQ3rbBPV_BE4Jxx zkC>*FQFYUeHz+-mv*s#idsMHAz`*ZTNv1291kim+Es$@drGSewO)A}?<;?54BTzy) z@$T&WvxglB#C+WM$AdsuK2P^FVT!)br>UVL*{f97uAcC6Nq`GjqqY~asAr#@2%n_`FGv|J;%dvH{o{IFR?96| z@o|iH;cjk}FnL|u`DNS49#px71E{4E!rUEW8@p3ya1!5+Vdc(~Y~UsPlXNs} zidE2ValVpHTM@d^cdR6g>oTEN7ccFb`!jCC(JMEHlZf{StmET2ZG1?wx}}RQwbwms z)Y(R!KHb!7<0dY!E$EA-)UMNI zyjvh!hGqoLib^Yk#Do+%0;-ZQt2%#TUw<=v=c_S~I0h|KzIfWKK9sapP&_-54V=*e z&s1Qi!#iN7mI1p)3TzlAc04txn);FJouD=2d_Hh&;z&#&eF2SQRv43UX*8K+dqa?7 zC}nDA(TO_Vsac%O_f%y8%dq4HowKuM$U%oT>()IqYeC?&5|K*>2=f$hziLS*q%)0(w z93A>%;-8gum&WhTX8+(jAN39eRV&XPSEDp4OLaIJ(1Y2`wNb3!53bzG{UKXCtpDWy zc=|{G=UTOcD2qEiv7S%I#I$15GKe@5UW1nV6nAJ%rIGd96&Iyx*QyGqqmSy+Qn?J6F9} zTr9RC!f6wg?(olm(*`XcJFn$N%3h3ms;Djfw=DI0pI=b$osJVi5s$%^7u7PDvl zppE10SSJltZe0@?$<-Q`-5r(pATNhq>*FX^bi1*0=YJ-4uH86@a2+i-#qeCp-JL8! zw;Oz05Hdk+=SDKA7=1cO2Chxjw$FvIpbaZ%<8-S_QEgaN^QMB&67324D;$GqT&uPy z+s&HeaFX-+oHY`1?>?Bn*q4x2m%GM)=LXf`E!4L4#x!Lc=K;M+B_Wef&kT&mfL3A` zrh!p742gSw4DJoiCA_$`1G`vn7EM*QTJ$Ig%coD*-{qW^5PFKs>Fb7%geExYT;_2`v1)7a~M!2=o z%hUPY>F_9ylKW5JU)Gm{+*5V^@Zw1!i)k``=jIn;ukR&!x8-4!Io~48Vb9BRXnAol zQ>a=Dt#1p@X+B8?!}O)MZ!fB{a+Qx$3v5L{B9x49DJckjHXh?o@|90c{*KIar=~*KY<_uhDyw zmrEN@aO6#Jo7R|kpqj`)CV&Od51tK%;AlB_&Q-)iDa#aUWCmJ< zp|uG&=>Cuq`h(9B^BT=4EoUJ?e2$qxX9I+F3UNS&^q%(7MnmJs$Ba3>!a-++f{GJcv>1<|a3!Wa ze^Iu|iwtPN^wojZ^nu=X9gL51KegM(DDA6)AU{PLwr&*E#C?`UXq;)=4HBp-!b(Ch z3iG#rtZ8Lun=o{yqDQ@)klm(HQ3fq9DilX~IEF2HxUJN3QP;8=CkZbCU3WJ^0F560=HIy-yd*yUj3PRJ>nl{LiX>q$ zRHXNligAzSdt79!&^YHaZXP!;x!CLcoSB;EG1cxRMS%AHlr5;%UT!W0RcCg9ZcjpQ zdcfCvcA4|8#Jmxz?8HlJ&zp1K2){Ag7LBE-HRl)I{L&i_;J3|?1MFhUqEY24%4 zIO_Mk$u#T@Xw8ah+cxLT#gp#(*WZ5mr(UKQUu{*b3{bm-fUMFT0hRSiKYRaFEoJX; z0F9|MNGDl5%v)t=pPv>p${CnI45APo7LhLkK)jv0)5XUpR@d3c?~R42SUJ~TzCXHs z6i_`|8@VcVB|R{35^(2yUtP|c%d%&usoqz6HNsv;pk3&%Ce zg;0_sESAI+I;;7Kro0v($~LF`9wcKXLS?$z&mk_kb16hc79f;66*-W=Fo5&i79|+= zlktFZ0R39CxQx7}s+q_Sm{S!6$KKkek(DA z9aq^tSr+&1%@&sp>})&-*xeaA>K&u9Nr;n!2uelU3mvBvP*p38lUow*I8}Srkzm>G zD!~-Q+_Ax+opr6dx@j-#>iA9b+y7<%t3Mrl;VZ$7H-dwg0vVY8s69CL@13gox}y?o zLr79Vdfjt6dp`6nIoxT2*j6cr0*rwI0ptN-lg=DnDTx!u$XMh89UQpmtq0U9l9h+`DsU`0_2PMjw6po)vc6sCrdBIJw-au4qMieK0&6oX*rA zfB4`Z{qX)jeE0r`=kqq~egE;fHyj!-*w*UtYW~ibZ^RuH!r9IJ$@lM`9`EK*?zW#}CyxF9eAN9{D`5E1f4|-`o z-Ztj^avh~XoP`9qJM>F@9ODz*j!hZ{vIf4T4Hx@Vh;ERDjakSqn8};DXyr|_U zNvm2?VY%5BltzTt4p=fV$B3)+f!Shq@cz76FBWoJXiPq#p5;+QIGGy-^h(P=@8=#c zdPD1!B0fcbsZ|_Dv(=Wi_aMtOXm={hVoAG{+rcoV%qpdljonh|ntD`jXu@8bjaJ6? zQ<$Evn=}xm5_QRwBv{O~UTF|*oJvSXc)n=;Scq|eQ+Rl&`z-dN9+JgsYr}xk6QC_s zuF=|ovk3()&xtfSIgd8vGNoH0)DEBEP1#W`nI%C!@#yz;2~9bGpw`>f|JdcoPdna; zb%$UUSX}JRjvdcIg5`>rhJ$(!!z6I+cAoC^w|ZlWp)fsl6RytE29z>ZmAq-tg@oI~ zPXCbs`ctmm8{r4j@K*EXisCn?3K?o3n){Z%ud`)KwUl!6vd%4!u8P9*;JC*0*<9MJN^4Y{#(_S_t?K-zC91N6z3JCk2m_9cKmWx5RAghcXZikKO-mrblx)B@2XNbaHkkm8E`Tw*wfOC0~SF7okE~6 zK%`7rC&VHMd;iw8{*9wiJoFc{jj02c1>>=J{Ak%oXLiV)!z19OK%2WU&|RpjR@N9T zEo!}70|GX|OtxH$Z%EQ9m%cTVP_eY(XM*GmZ2eQASAs>g{yDVB|Z# z1*Lk8IyImgyA5c|52v{;>m;;=giq4|M?~JNvd5z^^Sx7L2`pWU<3}Z>1e~Q~tlf#q z13p-L+z-xIjp`zgCxYTK-Br+Iey=Qpa3cpk+`9P2E4QtIbS@5;wId-N4Mm!SWz&vx zKcg7xHNmtv)>Lp#xR6c6FqkNG^5S^kKg641&@dbbsaE_sl!aOc zWE_FkEfRc?LD}emi-S2E46s%h&cV(F`wBCiUf$+nJnfFJCcpAc_G@1kpPY7|e%d)e zi4cie&;y899jmm-yL@jZ#iwVpRnbH+>!VtFu*YaI5EKoL zSzUPXg`a6Z9r*lAu)1TTmMY?yf`1eE4UY+O589^}UgC>`38D!!5lpw!_2lv+x9#rR#L^0bx4oCZO64Q1@ zm0D~y0gQ5KPVbef%kTX1Tgg$nU2W@%U{Yt?WR!D3x0^y=KHSVdxu6?KN13UmDk-E` zG}oO0THH_K9^IbMRU?;$h1VBE$GHP{^ZQTbdePtWv$0Smua~9^dgGUF;YAvVviY>` zl8iS-t!rUu83m@?s*AJi_}D*wk-0hK=VZ{`V5B3kc$!CE0{m*U=$@aj>@0Idl;~z# zoj&pUd&$9d4<|t`X89otX<4InimF<#XrG31{`yURIcI5aLiNnUO;cb)!*IK@cB9QMRbCX$#}8(o zKD^|{ivwpRw6k#hu_Asuj=jz<6v233kF0yFR;d zZbvO6VD;87nSb{`3|_q>C@N5H@B$R7TBxm+7msKUcH5$>>Tb5Q_12&U!*nv5M3imd zR7JH+pNBbbi-7`y8ABG)-icx!5F$hD@}GO83jaq_cwF1AHe3Wb6@_u0K~)qw zy%nz0r+pE2JDJ{gN1t!qcmTGwR$aZ=*kVmf2qTLbe4Ap{3%!sKN3H5eQSin5X#j3x zLkSU05uqt`XesLT0LC_+{obdu<@s!C%=y{;;iJp-`HDA6Uz~~Uy7&4U2m3wn1GXil zIh#h8tIx;detFT3zWUAN#TRNW&P(~svd@?1TYvdzwJlG6cz$-VGNbOpi;L_1-b>^C zJGYKc7ccJp}j065K^MXJAe@_1LkG5WL1jC`A z%ElWvvI%8k-tQ)1A7u$^(Eo;qK~zh>m+}AVw~t=>>0tDRH$7yZ{>7%Q*s2IVdS5S| zu?L^<;t?Br-1q~@x^a(Pn@G`BKl`=U2FKmw8#Cj2Cqe3Kr`o(O>cJp3giv!(h8(Av zvXl>>CPKqWN87!w+qu-0RyhW&_{Fk-BVgN}Uz7cH9v*^QTX3h zRTRS_YrZU_h>B|`zbO?9x_scJBeVpygk-yB!a}2`OKDwNyp?gRq#MC=+JwSO2}`zqExQHnRl*h^E4YphDEa8_(EhU_avX2? zaS$C1;~?_1_TwH4he}XlU4s~aNiU~zfQB|@e+XwlW1H_Jl)!=iV)zYXI&@5|EM6 zUQNjh3fxR;oD(wF^l=sj(C33<7(E>r8RC-(+7m2%>kDtZ@x?EF{Lx*wZW0KKqF$0p z*CpENsS49I4h^^cEEcxh(%oXE$DH+2^vBLh{lXyLEakG%Up`FEsj!9iG=?mVFWW@f zL`8vrD@|9b5m`le74vJMJAwn{fgeoy#BXKn`!?EM3;|+!a*|}O0X#02`EZG z?{w`yJMr6005SkPAHt4hDc}l@q8tYtrZLim( z-wy(4@M35J-XCa{JB3HH<6Q9PCyX8Y5&Ol-S}=59032ZQv%@uh5>n3a(6(~}9^lei zG}=)LwrX43rn8bt86U`ven*+6B;e__%r%BHMpc{N-FlfHPY&AxU_;58oYM-3b#_0R?#&(N%ug(T>q30djTQzS{j1ofmS4YBMb`@n6 zA*zi}naR7?MS%@(bzu~+b5<{{Jm|VU^A@79gxU%Jw7SM4S~u*;Q!&cCB*f_}-P5L9 zKV;>(aVNdB^aZ7yN6)k^7yRizkB1rL8!8m)^k{;F(huHFZ=76xd9Z&qHX8z87>8_q{TitD*EGUA-dwsdxZl9gUxkrhqUUq8JDlH~AufhY4;(^vUFceg8 z7^?Z;;AR?D@en=&AsZYU2+SFD)4SamBvUO+H=WXzu)7my@U6M?4MBg)6iX-?HXBYT zU~ovqInKlbzGG0a=SP0ey->R6)u8Ky0lSAh_1Zk5VpVPnSuih-f-uCt^wCW5sDk!T zpET=r8n$oV9F(gK?e?dap7bWYemW<#4l`M{gpxgu+z1J;SXa-=r{`l+GlU^cQ%3`6RN!G!CAZb4;&~55Gzg2p9S4r=kOiO+Aa;}5n3Q)!L$(_za{`bs zo}oM4o3_I|Ud_yUBMlShXZrrbN?2iH{@owc6agUB-=kVp&`R)ArV7W!^0_Hn^zW%0 zuL6TH;1G7)fuMaAhy)r4=&7S%bR|^lR8LwpmSyw+JlLb{S} z2B&g6osG^BW4MPt*=o~nsx;-(>j|`CLrjCww;RpfG;x&YJ#|?$mcVbWJBd*ipWX*K@w-@{0{`A=gfByK3Up&5iwEe?>cK7Oj`06`v z-1>>HZNLA1ux#G=@|#c2Kk-KcuT%9_4d486Z*+Grjs-VYKfRyVPvynJ584;5_a5E5 zwmd83Y4gZDzNptXt_}9uA=TQE5Th%}$$bJgApYIhgELp>2NZelf3W_O2hYwMIlg_3 zVd!g{_KP@ZR~u`SR)^hgs)2HApXXs42-pXzX(s>9Z@(~$mnYk588&bJ!rseoO#hev z{=L})N~FET8iu)du7!&_SIip@#H|ChU2lHsi$8XC+WWWbyED@Sj7lV*fP2TZY|KF~ z8s`3^c|97XlVJ#N+@fM_Ea`exMc{sz3+)F{4z#)1D$3JM*FITQX()zNdck{BY^tiC zBpwWNJVGg1n6HdBXIce|hrh5dT=nhU8$re{0O2KAl}9zjBtEU zzfegPLg3CXwj~8*+U^7ycbw7HMuKZVATG?)Fd4*KpbL+$U{hyT^opT6BlxB!0By2N zbQG>tQt>)EoW`a}wkP!ejqt11A}><1!4_&Ncr1Ic zxbV^lScdM|HeQ|}do_(?8+bdxGe=(V(7JbL#%z0mQN?i%6Xo@`BShYd*(kwKKA~^= z9iyGJMn~zR>-YH}Ve=WMJE0F(4HQuu&$-m0`#|`pBUBd#;7McKVfd0kJ_KjuN_Ae6 zWPZ1rZRkD0qbBI&R#U{u`-GfBkqS94WZTvOWW`xc2)LbG4?T*4vDcr5w8I~tl)mO= z&Bjyzl{W^XVYD%P_K?|_>MCe3bxwN^gwKE*FKFmPjK4oUG-^w+wc0GLKS{b?7Uvi1 z$LsR+vX~G0V|ql>!|8nXjACe>?NxOlFs4{*wc7L2wOW@ObEWTp`sD7}vSHFBUYJdX zH;)d=bAqW&MKL6!eMRWYuS&{~Xj*zBysY)CGJ`}|zIS`Nxh(5hMYtl!sY)?sQJJc7 z9>SnZ@+_2#X6I5tAY)zYuf5R!kAM8y|M)-uzyJH)_3=9g4z0~kf`JRFZG;^~XI(K5`#te+X%)$5YhaFq5ap_GfFrJ5r$ zrmCv-MYUMav*L~F5BG*IzPA4ClXCOO50mlBZ!y{v{mJUy$Bk4}2_OkJHGy6rYG_O* zT{7abMDV59Pqpl>fsKAD4);Lmf@C5{Vdx-8!`-1N6xamBbZh8+@(q1<7-X6Cga41H zHw&^XyRO5|x#!OJzB%X2%Brra9)Rvf10WgzNmw*3QXp-SvL)LZOnsQ)(1#-w3fp1* zJLKWV;qaHk_KzZLTKb@<2n9njO_`KM0t5(A%-jgr6wpPSU@5bgGKPf*gWi^(WW}35zx(}vcz$|G85)YZ;Ez~rUDNAW z!_a|RE@dRkZ#H2R>WBl3gns3r)kbAVGp46N@Rv|KRmYXu>cxbNsYvo&I|%$@o%gx7 zz>!>|7{yvp3@E1Myfa(VxT~5iH$~khm??)^mu&NDJRW$CR~f3CK{b|HvkW&!OWFby zb%7oo02#3~fZ|rA5h9@tT@PVn4G-{MFG|-redTr-hne{`hvK$Pfd_FJyncOXJ=aKZvbfRB2yb&V(IkXDIl@8S=Y_XI7A9Dd)>6JNra6 zerr#ZjpeW0NNT60TRy!M`I69blU8lkwl@TzYV<|ZjFovaTS~%rd8rp5Sk0fGCO4PN z%xmL*fFubiu`10~(;9t7Zij|UK|9go2M?m%`xr-S*KqBFpgG0!b^H92jP1Pk3xDUE z1i;gIUF8seq6JZvO`cR)F6S4?)kl{)Z{5%}e<8c(n>I8i-Kmmy)>*AeuNT>D1Ev$D z#YR?1xqNw@&8L*Dy%4Q;T?vXO@xeiVZ;QY;W|5^)5>$q(4T%^uo9II&FQ3zz@wPYDs@#XuBy#kwYhBSe7!8zm-J}N8FuY$9ed*=LnKh0cp>kG zouxSiH(S9-qyR*sbTerepNfJu)si-?RKjy96_m8}%VbTphVVu(Xw295_v1H@M={rz z(@U2MKC8ENc$i}xR2_uwz_V9%8##n=S-LJRU)(IxRL8cUOohen7ik?E9Tv{9Ketai-#QHFrq607vbf1Li|_cqT@ zirK8WIBhSl%S~FuflKjVx~$!P%sq@`)B375vRs)Fy;9a|crLajCezxDs5cg@;V=wr zyJ74YCN;hSO|&5mN3OcJaUS%sd;62aC_#yolTc^BZ4@9Ms~2~PD4e$l%i1t z4O?38<53fg=nls7#QF5JJRStU_?5fkLGb8o{{0VLZLa6f9#5|xU+=|y^!^v$eEaL~ z48QfgKlm4xS1&*Kc=&~{W*67f4}MHRJAd}rPSeTJ&ej8Ouw_l3CW9SWI>b3RZ>q5BB~+Eh7a~a$`kooZZ54q`TfOmBS_ zZyl9ai6;W_?lDV>ym57?deXlXme>`!Tj1d^}eL)xO3wyf{%~$%%q{JaLm12W_(A13)hrv-= zkVjMh)r~!+I9t?JW6st=l7T3+>S!LushHzHSG#EU0Yw#ySyGoq7XxEQk`Vl`AH`va zw|4EtBF)Q+qVw)(pHPiswUOmkx-P56_E=WcX&-Pj_0Ov54dWIc&JO+ z8BS&!VWp)?X}iSW*Jd;HrU?L#V%MV&DV#jj*BD5Un0DbT0Iya!^l2TseF9X*&&^cn zE7B4dXSI@c&xu%isM6PA!Bl5Wm1+$BsirK8^$HjSfK9>$lb~~1*Owcaq;9BLRYGD| z{~OZZ=dCEnWpK==)*zsVE}?LCd5!TAx|xKo1`%ul9W%uRs*GS!OqDM92LXoZK`_Zu zu;&ptV0A;U1A2Yv13?XAXhcG5l^Nk>Mvyjm?a=Lo#Tp{ww8bi9e)MF5K2D!0Qzq*y z&+F)pckpv#%1WE7I&Jiww<61TKK=20=g`}|8@)KmPd`hk5~Eu_8o7Pnx?DF4${2gS zDy{3HX;Wy5nu6crzK4k}xBuYIJBQ=(Pk-@eEoV>^i`WUOx_CbQh~g&(j%)eg;k#7p z{oeokk9hQr%c?30oK2zWHp93twA`S5^y+kxC$z8p*z=iP zC|%OKdpx=~bl)0Ri;B>ezuVh69;bQT---#LwGEDkaLP;o(0AoJ*T&(Gqk*ak^tV-0 z)$PPp|Lxy=?|Z-d_<#KFnZG~z`d#npy!dS0Ug!CC&pBTzd*J=dk@Ke?F6z;Mf+0OD ziuF2&wi22+ge6vUzaK<#00Wt}m3a}+st<$7-l1l8Qx%SI>!J{@sPpXf(T4|L`Z{cf zsHk${Y&mnHUU2t~#pQXvn5`BINNkvNOl!b%{m7_~HP8z2nIB6pQbk3W8l&Y_r?r4{ zW-JcVcegRjiLw^tekv_o)ORo~ZcJv!<|MpCTaqw2g)fc%l{rCjQHpZRb=vSCMZ+E- z9+qo{>1uWIAjah5c8zz7-8dy!w{lAQmI!U2re#W4q+Uv4F|f4Nc^wlpqxvM*hELCB zZ!}J`YPH;SA`LjP$8xq5diAwuNm`lc1C~uEFF{uv+g4yZ&y#956tS>+!n#bWS*CcU zfxB>&$WY2MYsZ5l#k{4@6^YIwjdR+lH>cwZ~nr& zcfNY;I5OYVDTbFI9+Meg$j=2 zK{B8QtZZ@0n%O>cecOd9lTD~yTJF}HchHVSJ&3RfD|75|g?5#Naq()iC@#*z<9p%O zh*lGo5p@QsBipkbH>Rc7Y!><1OSio0>qTf)WtleV(&6Sv+>N+D64AsN>_V#tEF)C+ zwka>sB8EH^EP6PVdJW7RK!WOKJnh>Cya{oJQ0G%T3<+iCN!H{G$0O7lK0F+}c{G~z zJ>9aGFHf^_V+;TA_%5&|12~798AM-rkyhs~X315?Jx+f?(a5PR3QDzMj?`o)Lr>bgC6ApFQaJ1=TQ>%>+Kq@rA3(9hNgVQ4C-LKzYt9z~NoR8(SGfgYTI zG&Q8hz;7`s7}^Ny!swUNo^7@82mNR~q_jslwaIhSU1?QW;8fIj@?rF}QzgLBzi7&4 zGhOB7#))(|f(NeU(*@NO!q%GtB~uG|JmE_#R6*>NRkg|M{riJzxsZj!ePL0pWJ?Gw zE9hU_;N?R;LD4G_!lBrm`j0O+7mMWnB>cv^2b5WomI)7u;qIP$*Xz^ zv7>giS$z7@c2KQ8dm-CO70JaXC!;%}x7+{V4-!ehcfY@TJepS7Y>}yc^X6B^#VHFz zM+DHrfImQ{E?zdzev;0fs@kna_ZbiCw4_?v7WD|IV32ZUCpWQBffeZ7_+}4fL<{s( zrbCbY&;Q^n?HBmRk8Zy4{@rJ@w9IO&Y3En@d{YgML=;;WpUM%%{*bb9@Nk#baU%KX zuliTO?0-txjMDB zg1fYhi{z{-HU!xls+I~W-m%KT)~Ugwm6d8z`nPssTM@d2_Jq3CTj=r`>*loJc*0v_ zGb3x3r#!E4wi$S|W_a1+SlEM!AqyN9ggO|Y$>HrHSS_x3vgTE8ENZmzwl>a|qlouh z9J-bjPW0)a7o{QIqqOoSJ!>*ho+zht22EY%_3XB)Y0G;7U)^Ms6yU`uWl>Ox9D;k+qns%h?sJuqfprDvHGNqIW99c;DcfNJRFPH!9J13u3 z_TIq$<`H{&UcE@<;kNV8_kQQ2fv zGo73B6$cvjROo6p-11bd?(R7}a;gPyQbjNBxmH;k@Z73MI7T8L7X?IPYHb^Un9`>7 zEfJ&C(R6PnQMg!^(y|(x0d2LdYgzl-eNf8-5xPzRB`&)v5F0{D&|12IohFT$<_B8A zxfciy=GK~LiTVM;)J|4ZvJ(_l#)%ttRgh%>+HLbG>dI6SCj~bPhpenKC zCQZ|;LC3nKYDM0hUMCNZt=gT*7&x5K=5Fa(5+I}RY+ylR$)c{x%#IO6K{= z#hReJM^VOcVNZ+kP$;lL%Yoqv)0ZbK8i>INM^P@w^0fS`qO=sZ+qK+WICV-(y3P3_ zcV#fP4_|ARt8{%Cxiw6B>8ZB9=2Xb~61-EOc8%H;gmQ3qaYS!qrP1)mH_*ek;O=QY zl>9ucnwkQ;L&`E)Pz)?fN&$4wYSoIGiB~VLhjAvAwY{@Paj$8hu>{#p#`8v9UMI6@ zN^k4>Zs`*0VNOFq&n|@}4f_?82CDhXGTs%Ii)ZQd9J;%0s)D|Uh6k+N5#~H2?gT}4 zbHb#$5D39*)fnqTx>C#h&!7R!MbZ9>;8lg=zh=$8^IH^YR`=fzC$}-7y+xUGI4;?C8F^c53MhX)?kHB?78-@0KjqWcx1sE&i znB(%<-dFanelSli`N7^jwV{l-(bk$GjORcjBWr{5n(!vYg31=k4~o-E?>DcnzWjRp zGhaCRm9M??idkpNwRPaBhClkh|0uY#*nR(})*pVaKXM|Gi9Oe+5YeX!k&?KoZTsR; zefDg{Z7t2o4mZlP%0@Z=LBMB#z_3KXjcmLMIo%aUoGItB_pZwnA&88ad z#r=tYHP4o-W)iu=hS3JI9OdwPyJ)7aQs*ze|CZEezrQ$NWsU0zYapDScA#KJ>4GII zS!DI(a8Pn8&YNd?MUQ1O2zH~;fm53UQc=EWMzbtxw5CnE9<(htkUaD2otIQFE z8?Bn)QQhux|H;*Skyr1(y|>A8cK{v&EN-)cszypdLF6`-s&JO3I%P)+uLZgmRo8P1 zdmiQ^OpA|@i-iN?fGXDlo}^HCrSg6oWs60&&*L04!vN|N0qZ^ zAg`fxHx)?x7$&u=(y=*3V>A;hxE*M!M|`8a&fz-DSodGWoo;5GYvHoI0YQ*zm4@!2 zqx&NsPM96xKtnH?o)XHptQK~`v^^WRKu}PHwsz06e8}=6PSYzSIs7adWAH1s8bFXrB>=ZHa$9R{PErQ9x?sC@PKg}3*582Ga`W1+p6mp+w@ zw#wGcY>^w&58O|}3vMl^uhzj^TYBv6-QD4ywHHQ*@AZB_mBUT-6{dC6h| z)D62S@f_OjDVRHHv~LBBNz_in^V8(N{FhID`7b^={=q4gNOx@p)xk>J-2U!QR&vk} z2;MmE)?NQUSx^7r$H{o;qK6;&)@aZyW=6-wuWE)+Ng2p?Bvng{zxDplPaeKk7HR+9 z18cMD?;iJeUZZlPY7$yQy}hI5`HQMZfuTIwVd2iv-A3!FWi)FX+v`OZ6cyM;u}xhC zLe=$#_7CNIMe#Hq5H7>W1kwUl*zKTd*YBpl8rsJERF)V4H14g&WPslaajQH7MJ0-v ziX{D=3&~%Cr1Z%R=|xg{Rm=l99voCGR&x#yX-|Ml)}4k)W6LDEV`B5#w_@IeIsmIR z`&=PSf_p9+igjS|NXrN`p`bOq%(9?p90XpL=d3%5$4EKB3tQWSj;uVZ{4Jl>wZ6*f zLo}|P_XhDMiEUW3=jI&6rh?SBG)zr&ps6mQ^2W0o_uxGtFO>VtHgx~Sf=r#DRj_kM z>>jw~x}`r=3q^GR?T@VH0OeFBxE>XT*e-M{sE%ymH%OT-Ya8Qw1v$;}y>@-YniSZ` zC}$%XhJn|os7@EzsG@Guyh_&P0NoEqTTp8dREt1P-laIwK;?}hi9{|0eZ`E;7|x0A z)bBj3{H85Y)L6oEAxDiHWB^4#y1x!tIOH^NzA21LE-NXSb{I~fxzbta3Ck=H<-l~f z?8XvqO<~|*?+LUc%*w(1gU_u3lN1s!i06m^sEi{gesx%dcfv3oYsVPB>suW>)BlsO ziIK`^?cK`Im{uz1ZKuMA6I-h@-ol!~M4o`(q-*iUD8oZx#0Y_f|I`1%SuW-q`J+E( zPR!nZr~)aI1q1*_k@6f~DVC@0ErQdU^BbJgP4|4;k8IoL6}?eH(JClcdAZEntO8XIzMAlj0fn4dRhq9J zJ!)&&fBg%#?->=(HZKxZWp0r=>3KUpQ*}X?mh%B0-gOV}`#bwyzZdT8C_5_V3o3(Y zE5r~((u7YP*k!p2)G*0z8B|s$T_lX!E?UASO`>eQy%PBTn$Z_<-YIA-UcGb-I&5Xn zjVITOe7Y%bu9rQr3NUXu-kMB|2BJAk=lXJ%K6$ZNuWH+c4HY4hMxelQTBwd{t2@9# z&~I=mDx)!~0eUxY;N|mHRhn)Zg~XQNu~0630J>2|9}hn8Ed?6qFMQ+YXoFpxo-oMW zH-;X@JI6XBtKKy;Zlg1Xw`(^Htp{I^M8L}zRy$YW0}Bpzlvo98K={!(xKxH2EF&oDS~+w_g>jfvWzkF~!DQg13$eXFSg&u2b<>N7 z^u2`7DIa*;hcvus+JcsP;5b^j3728d9}fHBx^PaeB+u1d+uC=-mPgKTi%KVg+bWqw z1CN5S8@RFOJpO1-NHKK8$yqkO6VXb)I;ko1a@(i+n(lVA6*)bt-S`u4Qsw&MBtQR5 z&t5p!CuLI1n3q^oCfgMzirXP-Y$igr+lFg4o=LYY=*iauip`~0?AXH<%co_!XNkY} zS09W=HjCJ7+5W~qf3i%fDyhHpQ+tG@FE5jl!%Occzn%K-*4{p0YAermnzTp5y`TG% z{~h`Avw3NX19;ntN^f4O#pAZOwkLt>?mPG19`{FHe-vuRrkWWu46v_9GN9*RGciA} z$Af6N6@~%0u0`2cXeH@YS`T|cp0x+N@gTITwpr%Y{)EC4TwKB^u39S9>nH-P3&{f_ z-`rTGu+G~7UVKz_XEm)NKX!UsKK&JlRSk^2(APnMfG`8DDMtjPTt5uLOtVqsAfS#UwfWKB?AGH ztT0CqiVs{U95&F+!ze}qp%?4?x2v_9T=N-qlK_=>(GP&6eE9ab!{iJ zhlCkr4`XY52c`ge!>GYDDL!kH8LgZztcfAgE)`1kWlu9Icx zjy>C{p?YJb4Hd9y93K?LIt=1va#JZ$ zxVzP-6%9t0Z4Y91wJE7o3tN`u?K{8n#?gbF?cRVw&FRf@XEMwxd2=#%3F7w%5+RGZ zksCZ1wG?ouh-xG&!Fo^-3OCalWleS9U-?3R_GlIq`Zw0-^bgDl;k8%>xi8jr%BE89F-YsZ}&KXi@YhoH~a2}zii zxuA;LvrO-%L;L2g5PiBSkFkfP~RJl+YY|B!Pc5;FtCm+E8i#1Kh zLzafydGEb&C!$Tj(nJ+WlhM-X#dNu`ZG|q#)(mPo-QfY|1nEOjRBKzDYx+Ia50vp7 zV_RXLqH95ckLq{&L8TV!ylB)iEojja)CX1y-Mj|lvG3Vs-8!M0=IEBXM$DZOZ(23R z+{$nRxr7pu@6whboI|^VK4Tn(Q5YE0M7sBF90bPZsqg}a!f8`b;RP{03@R#ZL%`86 zix8x6ph~}^i)4nsWI#42AmeyJ0dFq5lau!dp7EAe8UyIrMHdm%m27pllwMn|U%BINX8lSwDzKG)k zQwo4dD}Mdg{>Jr_lhuzuqm`+Tw%Eio;{RqL8;Z0wjCo_R*)^7T%B_A+2NtY{3E!?3 z;`MLva7%yq6G&Qmkrj=>-I;%;uAed4^7@L^1%@|74bi;1vLgq(2<01SJF2a?C!}^1 zhng&pXsy|SfMKqtL{PNKkIN`J|Nf^kFE}XFNCZ)jZYz|S!E-Lr&I#bDgU$ir;(D1b z&o@V3{Q39)_J8x{zxV6Gj-O4RwFSsr;hEDKp0ovgZ)vuDfXbc2&(!n$B{YcrP# zbx*MUYV1qVomSAZso-;4*H&HVZh9QY#M&-aEBcS^5$+Z7$O&)`&DNJ1;`gT3#$Za> z7IRvyIl+DO%hjWgRgs1FzF-A`q8wZ0#r64Et;RZS({(|Y6K&hu$L`jV6ZPq; z1TIFv{h@7w(NIMFJg+4bLD?iyhXb|~R=W{GMy*U@Gc0!FKi371?hMbwE^~%wDnw&# zXzVj+W86G@rrSByYenhxckU3p0Ai@8Bax!&;r`fRYj86=eB?29gPRAh}{kBzg ziv~@Rr}qwze(kUSdVetZgFpIL;7Xbe(ha$>mm%&iH5_^Y;LcfV#Iy<<^fcJc?U zw)yrKyeuQAt0_FLXEiDqdfPUjLPWUe>YG!33LlWn>PRy5VQBGcoa7E&__|T$(HL~j zpc~&*hKz(uZj;>Vc+iGRNy{r=u8U1-Inwdr?}+muy9U8o>drrvvSyQOUI>DcQHc3H zqrHKMZAfv73hkqvsN6J!X%Bw-;qqp>xn4$b&p;vxyHB_nQSocDI-?*Q`gTC(v zA`X1oyXQ;!=qw=|oS!B2%fw0Oy<+eHYE74(w=&}L)stm7be}v=YRN~(UJ!}pO}o7p zIFUoZp%;kdm0G+g+T1z$xOo1j+4X6iYyeFw_pEX9M(Pp+vlc}jr``fFpNhsH)6oi} zV714m2MtrpXc^jW%h^dj|Mua|fB$#Cy%EKqd~!BC6ieMK=JlZGzWb$ZN?nw1E|)8U zwcq(ar`4*zy&sJGdXtGFE%xK#U-{PFS#bHU&K7oql;_#HUFnk_w%3ou>fAp6xLW*K zJ=VeAyMYXGnyS&sfN*GOJbHVc*d9=A$p?Km2r;)Bg|tIdnp79d^m19y6KqPgwH*?^ zSr=4#%cmEc07Pr+VrCBMC?8OQ8Te7)8beTu-SByI97u4XPi_`7)m>GI^G}M&>AJ$8 z5IvzrIlk5Jd+T{_lmaoy0qJWT6NxmX5QyXq#dcVphgDovSvC9aZ!78Vv=yll0jgCMZE7c3L87>dG9uDoWwZ!D)zb zbZ{_7>v%4{i|`5ta0mkURuqVXo-?A|dPfz@dVLDUrZ!%Vx1LM10Y<(*3FCXLckIff z8NTZ`8>7PKqM8LEbKvkD=s%jw!XN{WvRNC|$j|pN?_}JKw}d%yqvu2=2rDjheS=;^ zu`xE%5N5zGr+`lTac`FoLQN2d(#I<0;1_{>+)}vy^HF@-nCL*2%_76lXu~oprwN6O ze9AK|q{R^vg=czXjz)dYwTKWIxXaUZdH0Rz)${z1ezIP3Uay+fi{$C2>$6$y_S~I8 ztSDNx(xUo~LLjXbh#|r$9^B5@bKM~JM^w2jR@W_hUwT>0uVxn~uRinq7}Q-^rR%k& z@~zju=_+?`a?IP}u)h`2v%99n)Y8)~%VrRGRHjo6`T9X{F-;=J z)uoOmUjK`GkrPa3$@A%Qdbz%MIk#fBE$gp-{b7F`&ayS55J%B#)d=6NXPH`89X$Xh z)o@ow9Hpi3A3Yp~9(y`%MPB^v!@;-j^^e}&Iyz#Db6TkG&%U+w-fpBf)o*_H;;gmr zzBb~LzfcrFLXa_%1dX*guy;qyb8Ubs2MS@9Rmy5G-k~7bRGX`ppYgJxU)R$Y>&-Oi zjr`Hp^vMVI=)m25ZFu}z829ScDlf8Cwn3S-TJ>n-InMOub4C@*?v5@JT8#Z(zn)F` zW~$u?l_1c%q)=kOnWehXv|E8;WI!CU8~VF6zsF_}m}4bS1B?ZTZVQKdJ~}(PMb?$D z%7Q6`)B>t$oc1qTM9kQmg3sYV^A4Sv<`&ADZo0Z{*jh%{#xR`?g5*vgbv_vSy!{?6BeU5O^ z89U$d9(^Awy}&Az#Um&erw>hUiC&ww}lUeQGil|ZoCh~1cK0_s`X@G+1k2x%dH3CbUxJ_{`vD`Ix?!yl%PW zWfZl2STC(|zRECeovir1eI3Wv@R+S0sj+Rn{VpHa1liQnbFLD7{R9nsyJCLd8tnQH z-)*1%iISD&2gbCAx5-sY!Ovs5D&QlQSZyw$x{P9kvJ}-^QA;=~%}hCIvy$0x_LEj; zN4g(1q2JV{Ho{(Xj{~28jzDeaGmx+a$Al0i24PXAU0!UqkKg*zU;7*Pf9BgorKXoZ zD6{99GGdL%iHdG`*;Eih(d(;h^>U^QY5Ok3O(_LBkmjswxC}_Jn2ebcj0crUO4{H4 zR<9(ylQ-RXva#yYB>@?ox*mGhVP8Z8FlJY$HIp$RZDsr*U~&(V7J9?gs;oD)rVpM^ zJ(aa#k7YN_>eRu2d(%@*(b#Ld=kC824hF*Uahvi?1Qbz(q;nFAOOQGvy)(<-^@ z_1&_tqy2ksFV1G`W<9^R-4cNR_(ZaB^6EOjnW|CWT_nYPUP73ZLWMaAYH{Swx?VO# zIM1AL)j0Q7o}!&thmmn@LG-hCwp>+UjoLo?A-EdAY1kWDpn)Ky!YZ$-dqF%I@4n-D zJCp6zav@x=GgLJpvGa~Hqx#)&2fvll>2Im=mUZ?>CQHr=7C&P-#}Jay?hIH3*axSnJ9%6YAXd5K@iIqtlP6K!E}o zMUt{$kgIaw$Q?DZG)JKk9CCEsP0FF6X<;IYl~&V-Sf|y(2^5DD7~^2@g0fq&zwOCQ zb52Rn^`ePi<(ui%$zX5bz&D4kpCWBYRkkzGnJh!6KMbg%%@M1754R8`v-S+0cMG54BGjJ-c=H`&wXOYe;@&yyej=zOr{y!+LI>u2qcetXqa!>t3V?AjzF zFrDoVf^UC)Z?QG|-RD;}bl&I|vHXTT`_ndGYd2_I&#HxWn#q&jT>Cxm-rw|7h`ZjN zN<#nzD@LXTW-AC{WhI=d+g3*&+vx|cu&!oBR8qrQd~viL(=(y3uhVK> zT;D&Ml!Ttka(f)YOTcU&2rSd)r66b9hAKsMsp$7z3My3zOlZT}oK}G~8Ap^RJiBqR zkSJ%M(335tm5QoV+TjS!1jm(?mpogwRB6;Vb#|83A-%5dQx=0RIG46AC8uHwMMKLV z@*Tq6Gs_u>+JbqG*U)P!Mftf0({+)n)`QhK%u>caEqRr> z=sA{Fm2iJRNm{Pwa(9HTo*V0Umk^P_Y3=7@c!X4Fx$S@XZn$;SUaze8R>47?efF6% z4q&gREC@5eJz413)>M~cM*TK?0@Ik&vsr2ft52hzhs`pnuHgaX<&xC z4jfjShG)9Ki)X1enOFB+V5wEj&4HR}!)SEq%cRq6qX<(|4OBp{1ENy!PnKo?-lWOM z=}O!v{+L>(7?Quk{}u?0xu&{NF!){&X&n(`LU1AI4w!*28DB^y4S1ukA!1UbAR7 zrcLGa9bZdt;Hr_k={xJwRl43ZdA0w>n_K&bRz1(oA73rn^>ne`q{D;Vt-FW$r;B29 zef^A(Xi(2y3EqYe-z126zF1``fkq1!BCB9TToUW`gAe`!5tg$hEpGPa^1 z#0wb?RKDQ~$GJc+D)(+etU+Dgvm9!Y!9>${37^{b3@F? zLUfsn4p?ALO|#)JN-CT_1JxOtuvz`ImlS<+D8twY82L>8_UBnwArbqJUBe^w)QEauq0b^KZ&+vyKsw~ zLQ;M(aH&?Ft?33p2MbhUz)-u?DkBu@S(b6}f-p4g`rOch=sIniwjP0BfFTHrSv3Ne zP_W6Q1&DDT8+TE4v%Zx032bBq-FgB5&|Tlz?laq?nk31nAWkT95@O%l-J(6WT&DCB zjv4DU^*_$d=ne?OXppe}fyu0-&;jul$ap!P+rs0iG*2H&Ll{niL$&HO9GU5u(;w-o zYTzX*iCCUzVbsTo91cypitTezZf?1rr{Ip{-I8KDA8Fl@d5uKqtv`kCC@{haVX(>2 z#piYlG@!b%WkdDh6}WG@HPkLDJq1+cBVRVA3jym+ZU5HVcJAJF-xBKdshY0Z_BpOa z`Z_DwY{{y**zU1{?sA27{^~;CKW6*Kyq~eYXGM3l7eXS~p@$Hvswh7Dky@Qtgl(OO z*M$@HS$|ijGrA(X=QOF}=~|_fC2ZI~i3(x6ESVQ`TiJDKPX9fs+X;JsfJqPGW}aOq zZJtL%8)M;u$^n+8AV>6vu!~NUrY!L(mnZ4sI)C`hw|@EW{}0~eU~_YRbN!>Dn$g2s zUzXFel;MmTjda&#^B2?Pd~GZn1Z^Ii5JA8XfRMmDrdZ%=50XhkD5WT`0* z!Ba!6++v%WmtyX!ZZQo~(; zINV%bS;@_vZJgemUaQub^rBGL)uwE(mn%xw9-PClwy1VSht)D_w30bg$Qnh&(lp0> zt|?i@6Pvl3E>j2*2XeZjNc&%EW{Gi-#0f(2@HLW3}sGKlvZT7ll zPAox|)5a@}O5tEKBFGN6wT8<05-bSWNjixJ{vQ&evpDv$>2XR62KNm{UMeqSR_s+& z=s7h&3H=}iILpjHHQ22ncrk?rO=xLLuFICXNQD-N0gV5uwUQY8x zx_xJyFN&+P>+PNGs2>PLa7H^(U4j6aMcxRbLKOAIX{I8u=H5+@qU2Cvh=Zj657A?$HGm2NzcfFYKU=-4JsI7JDRZKl3doVH*UD0bGi|+g;OBKRxm-E2rz*vga7k-^OZDc}`b+o1|NK|K^y5d5 zLbmznYW;^7i}xQ+M!WuJ7xQx2&>lH`ygL2U{No=g&zlUle2Dwe&C$iZaqzw1hJ#kvNW1x$J}QCU?H&hyzV`AX#G$g^H+P;@dIZ zUI;FgninY??`j-|Qia2Z+@3A1=}oEjVuD1QjT%ONQMbO21D5Hg2#jCP<#a{KDyx*} z#1Dnhi#ZM8lc3Y3u`=9?7J$k+9iEVT5+Je*c64i zy-6|CAICmg?izw-XkrNhZ~4MXZMp#p;zPR$vO4p1BTodZ5N;3vuK-2VbR~y?OL6{Cf}We!-S2mc!`} z6G|E9v84yVw-|?Oa01*BW>6?7qsjn=oit}=9AI5ntTwC{f)wBa3SGCxR2IYH1OoUV z#>uU$Pzh8fEPA#v(L}m4ZF}wx0|e~41`&qtL)#Ker-(w8QoR9~ha`|Psvf?6D* z7!OZ(Rjw&ITaQjQ&mN^~&U$q57fR-_2;5-bR;rp^9n)P}!yFT05iPOzZ6l^)}pjw{`*dt<$&<#XUW@WB+54I>f)-vq{-X^_?`iE5A zl}+P1fwFt_l`Wxz$Ri{-uOUI57j;y&v<07BrSISGr?Qw`F898CEE;v(AK72_zW?E; zyZfX2ceXxxc1@orNt62Qrdbyv;xdK3QFXq;WJY7)l!D9%WgL6hqhv8w?a5U!_WjpK z!9V}t^!tVWB}z1|c)X(gBAlV04&sk%EtB%N@4WS3FW(fKO}RG==$+ejlP8Vaw?{*_ ztjqPP&99eMEr(IOzke{C4CM4tetA|el+K0S^Q(F(mT*9z#Rg-=!InD_<2!FUUXZ7> zy@hUYjMcZSjn*l>;&N)GR7thjGP6NUfewqZF~BOy%x+3lYvBZK_qv9bp1So!F{e3Z zj*%)_Bw{8zofnX9jZh=J*_q{X!;AzK76xuL_dJL@8!JqG`>(WV#lf3|0<3LHP^#AI z${ZqnZe)+1scm?w!gs*HPFtv+%?RMNN3yk$SL z-+Okx+W4|)3SIHt9cOEg`%f*j$zUto0-9*~^5f#khvK!j1LrLrr?CFb=ssAj+psva z=V^13RZaunr9tdnugf~E2yT`ZWg|^^s)j2fy*vc#eF6qe>(Xs9VtN+rB5@1Kx{a{| z6|6P~j13zYHUY#-6kSS&zMU>h*>#v1ySiRdtu0M2Peb<#p}4LpOq@dNMj2+GAw8Mj z&|CPzK_QMu4^L}I#vs{pm?t=x;!tQH;0zFRw~-CHysY`{bg2;uGi5%MmjwC+RZ*!X zBm`ze`9WmIp`|%MHx`->f>k$6p$(=tfSwCx6QCu~Srw1~?fC8pb@Y_G*$cG2^)00a zJYa%50tT269A`0IWz8z1YUx-|iUE?u-L##(3F?Q|95wbLwEgD`>;4=3jXU~s?UZYE zKIJ^HB9HlR@m`@;iIo@ZdveT?7D?McV{6osN?rY!v#+$$Vv(o8N99b_uX|gN0b6hvmXGu-?s70MO7>n79 z^L&~H!wAC#@b8qY8`*>`R}CdJ+98gI36rF1tJ)>B%B-q{2#L}9RA!L~p!R&>#L$a# zJv;2Wkv~}9#lAZg z_CidI8UO;3`?_hW5>s84)wrHA$4E}AC@=T|lRPCQO09gZ>Y`!-NY{z&vY@46jfdXL zM`^lJp>O6tO{J@itd^}h6KV7uEQ8%$K?$Iad%eS>WA(@1!EA|{BIjK-b6X^vxqM}& zxGm=T?D_ZE%b%3Ryldo9UbotF-S}-UCXmhR1&Fye)Z;AUC~PQt5CL-iUSMLai(Oea zW-|+;&VEZ?+UeTyT8x5Gf^gwjjp6EB^5m`EIHsaa z_@;oASEA0eQ4r^Z*IV?ib)lMzS>-cDp)sR6KseX)RnQN{4+ix`s#}V@J7CL*CXr92 zQ!di=K+3()+6|-_y5q1%%V?Dr)4aV*vs8-E^CHWa=mzR#-8_CZD|OlMTJx(z>$oQZ zE~&J|x^%Z(2gOiXI!k8i*%m0SpfyT2oGSRF+4#2WbK0(Mg&vC&#sRZaf}3eN$~Qqy zHF!O2sJ1YwbAB)T*)Ilv@7r(x!6(mt>xXBr?S`3DUcr+mrRdAqX|8HHKg~}*Ze$rn z!#=%q7-4u)>-^r~&M*DUSGM~%|J&o|I`je!I*6{7<@19t2%f4W*X|JHy<#QXLI$>d zc2R!z!))i@^$p1w(y z;ZTxPt5gkQn0htL9K{$#M_O*1l#d7WR!kbsIBimliA&5V_?`#@J8Ye$sLoJhoEW;5q9Rg*!ewz<`q}QOK6_mPP3cgf2jD?Z8v~#!Tne|o+;!T zGp52I)PW+oF`&&b?Ll0E>Y7#Gl*9eIuU5@`b`@_AWj=R&=iX2I$tT6S7B{m+dsef+ z7WZVkfm}&jp)i7KbuR0qG3tYagxg+!Jm~M{Y35jc`c!4HtjhKItCOZKUE5vXEa+xy zs%4F+>oQfFUAfb< zpA_oF#ZBvZ5A5}_ELGNKNuE`-3#GG5l~qY$%Za!dZA3Gg?xsbn$`Hg+Ep7Gf5|h4= z!)5gcC&^!U@9uZcmydm~XIs8jd09|N5;2{+qSucPe0N^+lWB4}EhEo4>ZjqL`7) z3tDoOH^{E*q*mFo6-|3Q9`0<%?bVCf3&LQlWg-@}h_;7^@BCD~SwpDS_Ua{f(dR&a3cd-pWrsT5pmS4ZI_$&bi-NEdA=-Me3P+qm zYFq0ZLIk24L(zt>0)K3yQ%`%6?z>q8+8hlD<1Efwb81T|h$@pBc2sa+6{a}_Ua1*7 zC18l-S<9ewDIx90Oixvt^IFqq#aO6qnn^|!lD^-uX^GZG5UQa)1}SP_54RQY6{7eF z$CyTVl#FVyw2SKh_{aaKz;uI08N={=q;0MUbt`RODnWgrHo4yFmE3DpMNvN`5M4{V zuyX=y2iBd)y;xRP+KYJom&c>uIK5d%O~I?pW6O%_`@ztvC~lQ705S>K?u7(bs>*r( zk@`x{tu`c2IOnEaNcu=Wjm|AZzduo{pb~EPMDSax+ zxs|QDz;WwWY3{q>;ng(;@Pr{0fNQQgWMRllO;gr@?b2}YA!kTsnlN*r7QdC^Gv+Yp zn(D4aP5}Zlcxl~Q9$JN}Bjj?lR#8ytjvI{rDUJ*flT0rW?n6f20-Pcv!b&i~??$3! z-I&)9W>7^y+^{==nl$Tci_#iFn(HfT*jHnZ(kA=f$9%SMzx@@~Tj>uTTXn|#p=#F7c$dDpc=@py z_6Z&s0YAvQQ`jvZU+7su&s@5;jj1Ux7&+W6a}KK|qhbn6WXPn@Q*IhU6s>yi{w6K5 z({tflXg!+!K-g(GcJ3Vdgp~$+-cH4qPd67y?_2-%e|Y%jj_vn1IgD)Ai{$cEvRd;b zQElE*aTSC<{VsWR)g+ZSicG$3ApWa68CPyXHt+0-n!1sj66c@2fUdO8r7pmJHfJ7C z29!;arZ;u~DR#LA-o3WY-eA{xtSF}#g?o5$`zH3elez2D5=ngDl4aI zsD=#u{!o@`^Xw%YeJPg*F=X#MW}L({8wPwkA|iM~%7I+G=ejnndq}h8IlU~sj2(I! z!_JmCeo$T5ZIjZX_X6MYLr`&{N066kVHSx5n}AkX(3?GZ77f(SK|H%*(%;qd%fnz( z<>iZO=I^QqXjJ19!8QSLangm)coYaLCRpcpd}m>h6h{raG;L)n-+c72Sc!WDjMisj^Hh zZQKj=pBt6kil}yMeo1I>DXF+If;yTuu%m4^MyhWTV~zw)KIrrWzo{s)J;#q+n50rB zqd3yE1ev?0h$+FLi(m#DP)1vEAhVL;jsUmeHzi3Y?L#))19_cwp20CCG&~1J-0q;nErVi}flk(+5X~qod%H zKYMk#eCB!nXb@7x;V|!8Z%*Fbjt=e*-Ti?a_g+1lJ$rUN7!1DR**in`>7(RFk5-ST z<%Xvb2>b4U`93Z)tSG~?Tq$r2jJ6fd_}oC4VXVgN33#5&d|F`j32+wivUS}WdSR4CWGW9RSxXFv7&PW0dX;~!oXbw7evHtjQ7SULmU+oO!J{9&9e-ChDN6o z-`3iSuAYGSpzlCkt~DlrCMVctLJl1uSLS&I>#v5gREPs_#VDmva0>!8+0vT@1Wak6 z(V8oA_@Yz25k<^%O(LMs;qd|Z!Lki_S<6Inw@;sgmy8Wvx2_04HkN0JQ2P`NaEfmg zQtgBR;pAo0L^kXBI4)}oTIy*2K{iryqc37mUCU*~tOnIax={lv*!M*XJpoG>?f#dX z(S2W)g07P}^~H~V+`l6U$V>K|$(0@Qay2VXn9dc4OpR`hagBwesau^iX2c+v=+2gn z@LQ)H0kWFttdv+&fxw0;(l*fmBrI-V(@K&@DA8S^R_V{qFwJ!>ie8e?TC9XR(;)`35&rRiGL= zju-lyO_8rNw<+8Q);s^!e_Ur`IlX2$8muTpZ1wk=e7S1VRoM(M+tHS`jg~-;>eQHjQ=yP6%QNS3F0|V%W4puq zK7p7zuYA|KcQl^n`t&A$QA^La11U79j_O@% z`_t=3(`Eedz>mUGv7|8~8Y&fK?ex%sl7tVPQ7Q(D>}vbXJDf17?N8qPX-T*2`jk>d zdj5=J=j7g-R0*%1e^N|O?%#hW>Wk-Rua-roTo<%7h_5>$owIV?`a@Ra^u&>-x3^Vq zmv%3$Lj_iWwECX*11?c0D`>`}K5F5*V{!zXQ6PC{qzx>TkqFtQ;v5v z);Fur28J9q25|_ngSdusd2QZ?B5(t|4rw!pAreNm%w!ss4#pwDHcBIHD)UV?*s*&% zqYcVw#G2Vk4MMOlY2hzJHrkVKN6rgctEsAOm4_@mV7s4LbwrnrLxe`SMg*T%xz>}` zj)Y!HUwXQA2EDSPTVB*g7+)j>0iqTJvu+;6h%{t$FU^oA-H|@jIMHDf=AJSmv`Bkx z5QttJj7MOp^L|@Q>cp;6(e_2?+g9ki%d`@Pp&+@DS5rn=rDF@3f?b)+-)bH>KDTnE zZ*{tr5tTEX6ll@V`(kDkChNwz1?_y0pA>q;ylPQ;1v&Tq`QGP7n@ai&CxY*C~n5N4|lQF2=}8-@qC8|@z( zFbseB%dp`#{NsjUHw***u^Vl}t(NRYOL9xpNJ<>5SVLA-R?eAky6@d7;>L91L>%w6 zBPj}vF0x+cyEo#Tz1P~qTE>f<>18WQOt~^rSW{oTe2b{9d-sVtYz+N%_m8oNolLB* z5VPy<;Yu+e}$K8wg=n_G2Zi3o3+hX~rTCH&M7 zq@gEH$ms`<&wu(+r>Y>vHWI;XVt5o*_Gdvjzz(P!iq#`k`};5b-A`S*HFflMyDqki z@2RRed-O0{5&U-As?oWk}-lSEQr zEeayNbV^*D0dBz&d`!0(f%RMj@2V2ejHKV-tCkpYL#dI4Bng&aO&aFa4IU6d$p%yV z2(YeTX2FUY*d+Jh24@+RH*JT<-5ZyJGb$*a?F@)xwW8P7@aVwPVd!@DA|!-HG$Jf> zCtVk7ot2_!6tHoo{n(ek_TrU)=Nm6?X5PoGI6mGMA1_>Kk}n;KNL+{@*%P1r+Clt( zeK@__zWt~@&zGld?h=7_SR`V zryU`)*+N5#q=U5=ZyUNg7^<72WTS+$%AE#=k+v5&|H(J6f9bQM|Mvg9^Zldr^~*z; z>d{FdU?EMFtBWV~-M8pT??y2rN2uxB4&@|M+&Gy2$}fKH+WzC;fB*dtpB4dFuM_Tx zCbhhgJNxv2?#@M$eqm_QFuE z8nakB=bO0QbUN8~yDgE@Zk5Ajmg@+hI6QV?b&$Ag304_P+V*;Jf#GPILXtjzvdp5> z&2~fAe>|QjC}X!m$}sQ=KU8^1NprJ;u^zqRvf2!y$x1(YT%9=U($3bKte{g7?It_3 zFukz0(CI~~O`$Ptji&H|_HXy9qrrI;L3&A^!+zA$_B&1g7Kc}`??{`kH1WvNhD@s(^7T3=7t>6nY(_qA=p8Q zNPFF8OX1oJnml$KucVCOmX%e6&W6Z*rfxzLB#rCE!Wz^PL(_yw3!#_=DDvDI7A!0Lt0!`r30Y(j*Ys?P( zVA+SFYBc@Tfd>gq`m4v2AyTcPT&mADY5uILKWOB*@%Z-i+6~aJcLg8;)T?cc7-6{m zF8U#)exn@|Irvi!J4!j8WhBU$;Km~6ZQ!QI6DS=PIV>oz_XQYwIi6r^`hNbL&{P9! zD~l^M9K}04R}1ACyC+dxDiDwr?8{qtZX?vapC+D*)or7+oMQuzZOgK~Yf_qdXRbtgZNsa-hA-5 zeEeAWNFgl?)l&ezdNZ0#r4^g^4vi?SScp;R54ap}*e8@r z%otOU1l8&At4&_6HiQ)YQ4&o?1Z4~l#o5?f^tqa3VW+lVqtIAiZ+%CM<49O#mK7Ie z69K+E6qKPY<57yjuksL6a7bEgQ_weE-+$(se6~;YHF|PiMP_?21g<^WCc~Gn%UD95 z6;hQTUF-+i#|<7=>9EfkIH1PFDlG}>;s>qXJ_Ha?y5uxaPudB>ENbu2>qX0`PFJZ&$wS&^s1 zBpxJjzTM_Ud2JfIWBEV-}s;=@*2cctwo0fK6-bF#DV;BUc>P`J>8>#NbAV zmSkqtwW&AQok5Si)1?Vi6%=rwndJ*6oiH=9KH}^;_yahVFB=U zwreC7f?f*!jN$A8{EDI(#=_`f4M+5wMO8wtlAdD{`gH-v@mc}jm$e}HN{FApv4=@b zxZ%Y^lLSGbT5r*&S-0uTc&G`O(j^z0#`E>du{d2&9&Tl9x3=3FF%Zx@>H4uufqst5 z_lvGDArKZ-p|9dQC^|GOYEDrT>?8_|?^qK@4!rOpEQJn&q4f8v_yxKNL^;grwD9){ zyX*L}qgGzENGy92-B@kzZ1jhi4RqLoT=aH?x~1=8vv~rqmb2n}!|E~gfPL zDPm*K?)#r;7>j=455;hHc7Vr%XK_Ird4o3uS;30M*IGEuVZRVjU7-HQlC5|-^rFip z=Do#O*qK#qYkIs<=pvkA7ls}gwo%rVk;B3M7k?%T&FN7-=XKclcyXx|g93^U7q^=0eM$B(M~aCS%` zrOQ;it!h7s$-|2$?S5SugjM5dUJB`N3I<2>>VuEls0T_`RVC{uBtIO z{D}dD%!hYA@G1PJODkQp$rK%Y24W~s)+KgSuI-x$tH$&dqClxdZe5%csA+ev;`prR z9Xn;J77L=p_PGWMfalpZ(YDyO5~C{NrX4IjyXV5L?AlAg2$mWWFPCl%wo$c%i3OG- z!kiorJUFaT00}D=XJ~i^i!K26p*u~)f#4aSh3S0}{2YMbwhP7HEhp;$qk?ffx zqv_``9&!VZ?r$^*JPDO-be~jHm5MtDjy4#lr9a`h5DcdOJ6)xi@YUUw{RGl6bSh(@ z?4%7c3;JnS)R=y?#y|}EeyqpV_WjC!(^K&Hxyw_11Y`zL+^9|pE97widO(H0cjDso zkQ@3>tuO$OoqM|Sz3mV0BeCtS&4L{){|bx@8w6g8ak!k{kGgcd!7b(z8Wtj_BZ&7! z1b_|%P$RnNohpkk88C1N>b&$kzwM1LQ7LBxZgst^5cCi!G_lxGr)!J>V73yom#C|7 znG#DT5V`TpbA=nbuaFwu>l2|g$x1}@BcJ(dx1QU;lTznpn{O>>{s-3NvW1dzh&1To zTN2*rK7P-7_{>T>QDoNqu}$G7ORaTjb|zwA+IQY+*IQ_iQCL-li(xbjHsP78y2}bH zihvjiZo+8?+(;%2n(6aJgEk(c6{0GeC408#o8u3N2H;cD%PKXV{q@ViwU-h(!cawa zQXIc0KKbu`(;LdRD#{JLF|d>}S6OPOg@D)5w#*-&)$1~dLtHP_ViyeUXRMZL9+Kek zGt|eLvT3#z_YMPHb&!y+mDBGK@a_}@niQR`CB6+(55WLpHCz&36e!eVD z9#0QsoCIe_ovq5Nmr=YttH##eb?M^+;K)cxq~7s8oG#P$8x}n7Z`gE_&P`(ScW9k0eV zr}Jm8z5d3|WcCMt@O#j4;vz3oZm8h(?zS3ISq+5wBrDcGUsdfj=AIA2K}b*AO$Ed2 z(cVrno#OL1Pz~^-gu)O%e2{vU+`{8+8s$nv4u$bVVi}$1^LB!-O{hAjVOZdBi4P-e zmhmZlnwYm}D3}mHgJSE?>^=B{pgHZZxh;pL39M52e$wx(eTu{Q5NL`RU&PXh=(<#N zx;4ebrc`AT_|xGi9)vrWr+(;diu$20x4(1zxK+8;daelqH=|3VF}ng`Qtd@w|;we+%Esc?;V{yC{9mW zXESKk!0M8^l=(_DH9d15BlPs09U=h2CAi>LyF0^Q|MKVer;EQlx${v`hEswK#tH0V z(W*669{dThS7Fu0-|>p0x;)YpOwu!}+)(aw27&X9Z(nM!hlFw939IyMCmf9>0b&nL z54_;rLF5@{=zC!(aPM=Nq*@3EsFLoD!pSh8zcX;1&9*FbBRy7IG|*t#RxFpussSEU zf$70d>{q0ZfR5>qeJNJfpwB z@1hzJ0J?{U4u=T5D1KGgLoXZ;4lY?vEJNE4vnFq+Z#Zs(2DO0-4eQy##2E@#HpdSB z?}ADA&j32o9Hs#+ulGmmN8s2{sdufWFHLZOr}Z&Fj4iX)Dms+3dxKOD90Uud9t@<= z{^~Ctb8$p3I!d7zVm z(s`Z^_Pz1Mzj#`-Mb|*kxzi=RdGv`;B5;J}1+88;hyH66g+VOQ*)7ooYF#dz&@Vz2 zwu>Sn@pJ+yc3FW3DZjSUi}Yl@JXseP=j+F1xs_oAfy$hKyRt%G4JVXp+R(ESIh+QQ zfyWvt?uNcX;ISA-N8cSNG9gMIS#^uWGo=Yt?C;-(7CG@E-}feo-*|MVv6e@XA`mDN zZ;LPO`1IjEKN62Gin_HYf&Iqb=;SoLd24TxH4i>~{MN_k*Izprv|{;mxx83xw-`+u z5{ZZgY8rq3i_xQ>T==6ALFepfuJbw^4{sdqyl}&R;gg?#?H9hW+FVe+h%hXg6l`zm^r|Gig=#Pv1*0L?buk)CfXwiAc#G88 z1(Ay(E&zLs)P@v>L`bifcO&g9R}QnX+#ip9DNoLq6mZZp23KuSy5oEo^!i6W#tQv_ zF(uwJT(!NXwp>3iG(M#i_@ymf-FCQ{ z9sv}-{n9H=qtyAi?e5ymocKkc5kMM;CsZNpKJ=rZ-#dd+n)3o^W>pA}kcW&MFgUqy2{(oXV~S@BX5%-A^b+Q55$5kn%;DmrPIzQecYR@nBgBdgOxO0Gk^~r| zh5n(CZ@z&Z15X|9y!M&V&6o15#D1+iFs^SWF^i8{FtsG~m+ac;sam=y*=O9v&ck3v zPuARfYCU>t&1UHQ1rG81+6iEzh*6EsI$w2lg))iL!%fePV(hbez7y-*Lozx>2+{==JJea*G!i=%Ck>SQn6 zW@`Q*+niRN5bEeG`}nD;>5d0Y(bV+4I*k)4(6j3I!x=-N9#d}$T_{RKlrcK&n794K z?Fo;?V`OD^QLD8h-DvDh_WU~UnzE})DCHNMvdl0EL&vSj*ScC;YGLctwd-W)(!FY0 zq26bN}e#O%1r44P<*N}VhAiQ@voec#?7<^Q4f1t16Js-y6HZ9&b z=q9nuz;Cf4+#v(_u0KG(uiWO@`9{~Z3=lq0Nd6gNSUq|&7`DTaT%Omat`84oxoy|> zzC5_%Qf!0M3kL}%pLF)HX4i3*3xiEv!}e(u75$KYGX#Gih1)OEhaL>pTzhp|U7S~W zNl4L&cf|dV^37R`TD1dvfZ8(}J3>}KEJ(4e1@DLVw4k52^Mt$JT%4XBNl*Ut-5>Y0 zLn2lko_h$r3iCK0iB)Duk zWA~c7h{DguU6~{Y5{uzkKfydm!&Up#%f#R)GZCET`FJdj5Wr+e|b^-uq|yH7uILa{fb^AG<_ zh#f=zTn0$I7!F4Tg`TY^=@q2c4`$!~^`F0SCH=$u?>(*?2wuXDgHja1F+16pgPkB8 zN*M|-a=MD`*re?a-NnZ(>}y>2`d;uW|K{#GvUjHuz4q7@S7*^U@n$?NN&bq zMIs8E-6(|aL+sJtR#h$A=HeL$#pvnJ#H0t zH6kp$x9IRhiB}RIC|jQR>VbPd-HqlOM86s>p%{x3QrGQbuIZWZnmjA|)03xM7!rO5 z1#UEPgVwlaRn>IL2(DFI8p8hix)8aTxfWyBiC_Y;k~VPp{I4 zB&~{wh6^(eEvWdm)` z%FcgcSLGl)*rl|hTc<87BRiEfa@x8h!Vz|}wbZ5y_Ya_ujRIHOSKRvmXZJ!3TBFRX zv<2(PmbZ?0kK6v)J%-%61?@s@h!tC*#Na!W`7{PUU_k0vq3Z;$9ng)n`sdr5rb3tA z!;{2c6LEFbLX!3}@%Lh$UQeDEy4Sg8zdO3o_p&dWAa-T6Gd`(#c>J0>cS zICR9@+>|-~RlU&$TYde=g@e&N_QHjWRp3*&;PNB}X9yB|iH|X8f>;<4!kioh9~9jY zLsc+N>_Ap|5pp_*pw2MT6%2UMpiq>vylzuk+qx|(e?0JpQP$X-4x)RxWp9-ZEwdYW zt4x=XKpB&ASK!&B7}<6ZpewF>={qqUAJXxxVKN8L@<>ZVNT(>=N#rJBo~t)!{wG6w zD#W#M_}!!04xC?keg6l4eX_~a7hb=7(TUqHUOPKFnV-+ET^fJk)f;c#zIOBGj!&U( zK7V$+UKFlq>rcNt_~`o=+l!?kDC3FgmHjV&`R7JAKKM&KaE{CG~K~?_tL>l>4kZ{b(&5#x>}t&s;~k{a12{sdCCWfRlu-E#dESIlW7V|8eX81SttQPW1>4YT zcc23AyA9?GdB3X_HWa!p<*G{dFLoJgN^GA|mR-w+2gn=zGr!EWr~z zmcGZR44Uo)eXsv~UFG^>-gTF-;zFsKlDrEeCkQpt7etepI5Xh@3Vg(GRI3#FDv+pb zHB6IjL4inDT~4gbb1IEZ0=ky_*TB&A(DVO18QLn6u!lq|J2P2L|Lh?d|K5>4_ zPyC&|sT5#J^xN{H*rwaXYC|_H&&zGP(J-=B7<&1cfKV7kb|~_+q+o^GAJ}S#L1l+c z8!VUThk~3S#D|Ed5wW6(7y5n#-3s`#0NoyM>e5kRY72J&)8i1LS@cn567!~x zA^3_#yAC=t#D{ofAL~+@0!1gfV7mL+-~25R$n$5X@BPm2+EL z-uQdJJsBt2@rf$)E)34!y;EI$WSP=ByTI+(yV`y?!+OY{`=9L&GhK26jP~yaH zQnWCMiE^L7D7z(OGKrw{L0^MTMCi4JxA^$udUI~Ye#_sAP;(U6m#&7!cUzA&?#epe zfA#t=eSUrNS5;a>Bk2$2{9$o^l9@E8<6R$})@O?-iXBfDE1ZsCmvu*<<8@*p4L=ss zY*l%-fxv1U@pd_H6LSfOJ*dDL%I&6UGgs1wg>mL!?6O8XYGV>atEf}7X1W};_W(Uy zjKczhb`GVus`3r74J@X(bj;DR!`_AYnIu2W*%S}g6R(YgbCZ3nxdG^(zFx}cP0TLgEX%etA-$E5?WyZUYTyB ztdlV=V&GesUPw-#RjY1qaODzrmarSg9y1W4#&I!((QP{>_|Vp6L(c^RZLX!Ds`kUu!?D$nvxf69oeO{vHOhEyRqQXIL{{l z=~;w9bmz{ycR%{T;cH0XiO%qJJU%-+Y3l;jP*-rN9zfmcjaT}`3FchDQZ)|#^y^9l;CqH9=; zfKHi{8t+%LBaLpWq9uY%L5&C4SoVQ9Z>zEl zqvpns=zl8f0v6MrOVBggiAR?wE}IDYkx!v#v&`B?-FWlG8?%GW-NpO=G9B(?gN}kJ zrA|4D1A3RE>G*Z|_zzDep1AXqkN1Yd>j#rTB**)cKl%SoSLeEoL}-h`G`W>iK9ZeN zT4t+ZY9a~!TEWWOo^Kald13tD|5v{~e{%AZk01Z<|N2PPu9r)Sf_67(3BO?cu@>4; zDD-3JFaJD0K8xcCC?f@8N`-V@q?8s!)QI>g6k)L`&=KI<=4W4c<=TJrtzWjI2|8`PIgYwjwUkN3r2e(WykcapqxQ*x!e$-fqY9-(%WmQT3o*7m%6>kDl9y= z?Wb?=B#FD#igH}&i1~${1_EXuFe&UFKG`;-Zb1ONh45lvdvPSO7-~C{B*sSzD zZmm=V1*W)FZdX||o6!gEVmh3)Zc0s`s$^Se_&`E07-$ymNFEfH=}hxD3BUjWgCO>N zsO55xjZ%`b9KSIb%OrfdH?Tfcw0E}kJiauu58A?P=y7SKicLO>2l2sW`ntu%s(7;0 z>rTf0=+)0T-cIx6hua75V{09LsoeO3>JH|=QKUrAiX|H8BWj+Ep&tw^!j9lN5b>iqR2UrpEHRx-JN2bXi3g&1<@^eB#nOe{%0LuiyCNpFBA#)vsQi%g40U_}+ba7`CAdhM_$iEVJ$MgZGxlk00HC6bG?iW+FO>r?>U`sLoP9+0|7VNdM}! z*KWV^OY^56{r;c*GmSO_EMM#-bPi@t7#O;H4<3uQLKD;BHZoB@pRPe=9i3{5%Yx{n zi+Vs=qD_yDDX2+eRo>#(I%;u%zVt(MzNV2k1{|he1$A;_VkLpljxEV7o0wV%p}QiL zL$i8jdBc`2TX_Nv7U{6~pkPUeAXnQKzGZ!d-8dm^jxc~OTn&lgmenVbsWDYzLI1a7 zJ?6eXcsftd<{KTB}A^(tYl;NUaA-+31=a3 zvQ_E~CUpJ%4FEKKd?=_YPOML!m3vP7*Qcvrx;{#m<>s=ue#Q0{c5j5j&1;_bcI~R_ zo_xUm$R%Krt+4+Vb zyEPm67?SlA>uGeG3?+Gbub$=X?--~xAxW@Z0Z;4GEgDD8$j70xDatf* z6E_}s>m?;j8>{)s6q`CuAbE!MC+-MCE0(>B3FjH&Z^@AUW=lhc%i(v6890cdY2MZ9 z7cDy$W9y^6;cdqLTK7{@t?A!1x-Gh)#JpV=a!m};A0#653^v#OI?V`QLcN3?9AQ1n zG?Y$6G)+7csl3b=O90`~D4)+GNf=xcr`kIRSBqxRO{0T-BtI54QUnV4AwcGrvK^~s zHVp&s%I%BiK1e{Im`8Ga#}DFY;1|n$d)_*sP+d)2y$P{&Em%Fq zZEVrFJW1m8ywk;IXU}V%_pbnko~uWoKSm7rgLmF`UCZ}*uDM?*?+1PhEMAC4NrxU*Q?LkLFGhfBqII#Z zFC7F@*=5S{kCJt$6EE_kmR_bJ-Kyo`)`Tw z{j-l^n?iv(=!U6rHddi|)o0_>w(SRQAdLt*c@TF0`9Jvd!^cPe)9<|ZuYUOP<(qpi z-MHpPGAq`Om$P?;r6F`iG|1=+XSL0{VJUq&1}Yke@-eznIL8?6f_)}L96a4vwW+t? z`0R_{{N-2Y^6{TvJWfp)NSKyUf+cc7am0&KPmGQOc%l(ik^lGbDl8aX-RPCmjUWvoZ>L8Ah^*N9V zAa7bcDrBK0#90OV=nh*-!&!mVA^38+=1ORPI`D30lkdpgOIvGO>#cO1I!}pk)*XF%H%F%U1qrW5E@S%HS4FR?Ft49yd6`>I6w{AL;!|~3m^yrt5-iaqSnr&WY z%TN5=*N>lmeDA>rX`Z!ol{9_&&cC{EB_XyQkCt``GbWDjpkMCZWxZZFn+u=>jHk0M z4F5?Ry)Q~HC`Jc#^gEV(f?PeSoPpaNNNePaTz4;B@}oe%e*wh^7=Jl3p{#DZN;N(K z1B+)cA?754}7lh5*l+U?-6v_E;j_9MIgJH zg(4-u1-)BX9oIFpRaCIq;g$7LyOuJ5+7j*EAPaipXXU)V@d-zPkyxmJ_&T(qxhdsv ziOox5xi~Erg?%}!M&oErJXS%-*57qE6RTOZFO1x`Q}JW7{n{JDw;q&rXRnS5igZ{k z~DJ}psc3s z=+lWw3!fZN0#v)5K-fv-xzZgDW6zg)QPxYkwJs}pG^md|D7_1Iti*6Q2DmWi(!oOy zTIgsu0OoS1&Fh8RAQx$~pgW5{qTcC+616ru30P-(9M_bnhypMa39?l$ga=KoU#%Ma~E;l!7g&`mQ3{6>~ZViKgWYW!#i46p! zouj)CqQNJkP!5x5I(uFCn(tO$Wp@tg^AfK;&!sR$VY~BI)?PNmc7}e-pt| zY@e={?|fi6mhmM-;3czJyjACQQJRaRd~>|PUhh0t z%e5fMYVq={U{z#`L7Ma2DFX_k^m;JhBJk~cEiM+8d2T7kbccJ2G6-5u zY2kD*+#M70tc%(d7?*6Sooph3yq7Nb`13 z4K*i48M{F|;wpg6E}E7gE^R26(r0ssBx3j0H;~;mlt{% zhuam#AuO*olD?OaLQXGBMW6&_4inPF+zaTyFE6&UtBTSBJ*kWNYP-zo0qyONAHRRR z&1;q`wX{=h^Va94|J^@%Z&lf!`_%2LZ;U*9SZv_~D;f>_ zXH4S|5+qJ4LunvC=N?Z_t9%#5(&;W|K+zo`}J?W_NR}Z ze*fbmf96Ibrhv9nWe`>B8mkrU=ClBgq=y&N6G6cX?W)L?mxBAho9Abh3Ek_Ly*EEK z`lIs=B~}Sb&F!RKp`1hZzuOAL#dR+pIS$g;lfnwi| z2^T6ze^qsh23_maRZ}!g7Kc7% zOoI!nB#vWI$P`7X%S_1#hL55ZU1ehg$-yEuPOH&PZ5OF(ik47$5E8Lzcr^>|cScjd zrYB4pl)G!t*TM`q@ruC|`@VGveK*es9mN`l%@ce`Q*P_5=IWmtn<8h}SSyXm07#@$ zTA}yV+MwlfJS5<&$|@cNrp@w`@8-u9T`o6~1Ys%uRcYRfFFSM}d;ZFn%RDJ4`pzhN z4nC@-5QTJEYMEfZKcFXXrzzqZ{~0tEb4d0z%3xQ7B5yGw^kS8U`>d{u|?L1nozIGDJ^fA&VnqEJgy zbGH-H9&O$<1z4yG zyBMkk4Dso_5zwS>9TKl-9pB-6WKkmP3mf#xYSvFi!xJ$Md-E4{yBnB+<78Ms#%vZw zZ7ISOybQ-;B!mMtDn0ZM!n}>WC^uE*c1{q`=hJCXt?JKz>fq@|kDonW`KtNP{?lI% zY%3YXU;3KN^XlS!ap~pTwikTk7eD=1KX~-#-}_+Vh-;3sA5acb+0k6(xgY_2~Oex@fl9J3syt zHwY>2uhNyK=Pv{BNGaMBo?_5vYO%*=gzLr$-G4E=E`Z9jXIii)6NcUL9Z;p&Z4V$yVUkWo}%+4p##^8 zCzs$;;;fkqf*V*0Hb(inMJvOSW6abWCWc(PH-PyEqn zczks1yOdyTrCAw8^9U<9vSF$!AV+0;lE=7P^L!tRP@4oVV=qS(3!XQXS-z)W`Qln- zt(VQLG4XuI%CUDTwgg&IV+y;8+A9P36Tkk|PuhpJqo2Varz}w*Bc>}uY+BH@_oaRP zwa#94ej(`C`_pbRG}S_IeTtnA9jo6n@A|T`#q((_7EN!^cLxx43H(i~Bg!BR_Acl@ z(_u^*s=%=nkB(PFwIjIT(Ib{=j@A@C|E6mEQ7BmFk0Ag(Vl0hg-=BdLW;kFis$EZ_ z1kW;eEw9``^$uJM6;Ic5VEBanVhqb*DunMuOH>AU3q3~)U()i?y+KjF1uI0=gejK8 z2@11}h}4bZeKx^@6X3@Xa)3vCtz@r9WB}HAZIbOF`c-=PWm%Z!#k1i7To*%Ins}jB zo`8%7yZ2IDMU~a?=%@7kCf~NIaryy*wv$QJ&>^?sKZ6CI_SxfRv)+5c6{;dc<05NSHAEG*L!o37WpDOKRUZ|{qXwr!(g1$b^HDQ^?#{8JaLFM zQjD68wIk}2l~p{p3)H|($iJj$MBq6TQ|Y()l6ah>Ay8@tAzc+r69)mo7T7OcEcK(O z`O&d<6pu<1bLog1_%T6WH_fy)2}MJa6Zx&Gw=*byuC7TS^Df zfPTAb8ckP)SQp)u23vvG}+0?XhL6K1d(%ezbxIocxTF+_D)X}P`ALY zip?{qxPy|2a^SHjQ`gnl=^zN@aw(2|c{$~3{_MPTjjzVVa<3O^$4)1wARIOtYP-5wRBchE^gG&caM`IuAG{QuC!DgP{vbtaX`YYD9`BAaFGYL#lug{gV^{B1d$@t2f z`#=5HcgOJ%C$O_#pN;AqVjpGEgs|;VtNAikv5Bic_|7}`j<%O?U7n}u;$pKq9)zPf znFK2LVPswFMs!g4tIgm2&7Gsc>L~5<^(MfqgXPlsa8PsiB-TXf#w`|`i>D|5=pX*# zul?qgfBN3rZ{1xCrWDOOcP7!WQrIBJC8@z5+YQkd4+NW)1cRYZvBg$(es0cwSknJq zD(mljeSdb-UwzaO!-;l65y`8&Nu)J^sMgs^WtDmB{rPB^4u}4w9q8517nQ293*}F} z#a5lqw^yzur9!$qP0KjMN_gG-br>g*o>q3SlMv?#6f^*yoh~QCfZ%x7v`OMarI5KY zkuBJ%wx|}-kqZLZG$VkvY(f}B$;Dtup$9?$3R99c*OL62t)nPO1aUy&D2%)yaIyWWabo*b z4#U+76vm`LwbzBrFUAlIx5D9l((ihsO}(`r!OWx{H*M?$8Z)~@PrFjiF#Dp7Os?-a zbnMnoDb7}wXKPa~?imwLK5@;qaxb~8H|OO$_s}^v^oV-N1r(VCK_iIEy7WIlu82}` z=pvvLts_x2Fq2ET+xfCPUEtz5&^b2^3*;JGAp{euu?=POsdsjFD??jbI*=4>i0726 zc{Mr+^0a+$H+4jyt(I_Ga9M2Ts3|>Jm+4WPxZTRCGD^yL3`9pnwl#i|`%^-mgBL>Q z<>}y2R6YpY^Ho=@C`!4VRa$P}Nx1yd3q#Wfpf~S1!)v#*Y>}Ew_`b!Ho0;q0+OfW}AAaY1 z`M>+E&s=?FfAGTo>MSpnjz<1C^yc~Y?ne(_dj0i(`hWk${Af8_WWm_GG#&i$TZ_jv zp=$G6KYyEu&^ssFzx|cV&DP9oOYR1CrFO3FdXo^Nm1P?zepGvb=PoY_ef|ixJGQ?) zS*W7mEq$?EoTEMpDJ5ukV^-R-oBK~uiipMnv=Bl?-rhBD_mV2NMwM#*1T$2yn`9|Q zt9QDiW9(xTm`{gfz%hlE@(oh)X4$E!Pl$lVqrNO$9 zN{Aq}wTI~zw;$eZMWyxr3-**A6_2A^dCjThWE=T$rJhEHDZc|E)c(|4!8Qn(BnO2($a~P0NtDteNwMQSaVD&Hx@y5Y^Dr6hIu6N%uFp#zT zEjiC?!P$LK0uK`Kj_9|Toig7xHB>1uF$k3;ctAp?9MiWD1ZDl64sB5ScXf>(y~}c? zAey>6{Nxuezxk=@CtjTY;qPvrJU#r@fB5iU{mzGf^!vNN`ptt^UwZJ-eelkvo8Nt$ zEf=@{*5`)%yT#L!M}PdC@`ry$Ko}l&(_wS_nmHWHyJz~n#}1q)Z0*@?RT2FWtK3|i zo827~kKFABRhiL_RV!X@Xxc18WvOn;ciwNBtPQMAN_x5w)be~8%f!{b3$+^yZ9iRG zX8Ejn<=d}|VY0p`v(lko(rwdvzJL)@5~2o+N^pk`h=4tTjzdsXgQQbXY)->I037jnWD>;U*x)mF_&c$Cm4jn zvsnBaBUS|A==y7TK5zlJVF8(bh69UVcCS1`Zwnvrc^!bKHF5f#e!m#p&Qx$#YLmS& z5f~PuY#H6c1ps%23A!5uHXZ!7bliqMMT;&TQD=;3_+d!Y4i_L0O$kdW5RcQ7AkbKm zZri&*-87UBUq8%No2pRWXy67ueNGAr*7FrIjR1ia8S^|{uwo3IxhV1bL)h^SKE4tn zF4!zeWpuabAVRf)uQrcIxfHu8m8@VY<|HnCB}yDsS`@kVh(!gxQYm;byVN?YCc)GM zdYu;hAs~&su-KELV-rT!{dvCZ3qLX$`jcTajR{P(fcv$@)=`j{Kxk*(L6m(I%D0Y_ z<@3$?g~g)d;mCtr0S`$U&!T?@k>IumWYbh+cMV=SB zZNdFjpQl1t+5)SP*k0|3S_7@qs~{X6^2rO(d(n0ijGPpGCj!3M?sq9sptDh-@)`Mb ze^p)&cSn2U@Z#x$Zf;lBVJNR1?oJPe^Hth;*7Y|JH>cV3VD#E&51Q2mHmSAVdto@7 z4R77vpC&P#uGJqF!ytKd=Y-zRZ~PkvgR!;xI1NH)@7m7hcpVIP>CyVR{H@O)e*ZXo z^e8KuX7?bueJjaN&7BX{4;O|K;Bvk=KE4>h6=H?WLOox^d7L^<}zJ zK_m&9sH(FAB2LDZEYVG`hlr@Am{3#vB)InQUu^0%bVaZ4xL^L&W(dc%NL@(UBwBA(XQ8*nEL}(wLlw}1un3F|b63z|fyH7U6RZ$ve zz5Q)Xh`Bo)5TdjuW8aJhbPS3`wv#yPyxyOVms?e89XVDQ_&zar3EJGE)!6mIWf~1g z3rnJe2|S{Uirc`Ztd*s(6-GHjp`wGC2**Ta>Q(e--HyO_hf}Sj?`j?aAX>9tVkssH zC=It!U~RI7PV}`ap&z2@M29C#T=zmw0cG(CHyd2GmP6Uz|P%m9+bEB=@V8)VCt3}!K z$umn=Mnd}qc;Du+Im6<6MAhj}vJIkt5VxKcU-6@fR~8lBPWmNf+AhxM)PM zt%#Yc(sOnkY>sWcneF7dI<@rJg+0fzBDx72u*%$BuXsv0aJ+L%gkw=oTdOpfJ5j`* z!mv&^gt~O9+8X4+gE0W6X&qO%dw~=pe@e)@@s&p>kiH`E`RvKX?8Z)T^B|k&5{l7q z1qI*=B=+&al0@g*UEa`_kH?AUm~`7Tb*H!O!O%Ni)4Q{Gq<3?Y{Pf8xGtI-bo<&L; z*}86Hc*FvG0>q`;zLg12T(`?jH5*-BXXhsJ1y3mvVYs~C{{3Hg$!vTrp`m_&b`wgzyGYMtovm)OlH6PXU~r5EbWeVnr`zLJ89*O zeQz&*`|YK^vJ+lL&vHLP!G`EO=D%_`U01b>5gLzzhV-hoTg_KcO5u(v<`?ZaaR-z3_?ca0U86$j@@5)u{?T)ZgvV;38iO-+1n+l< z_;s+0%R3KrKoI(s3M zA-uM-FP;{MiMx|{8yik=N-sL@9jP*7kQNBU&+WW)B+x!Y1+ zgRmj}F#Q6?6hfiSVJWswf%hT3UGxNb@fZ0TLfxV_yrsWNTh?w7t8g!CP+xzbgWbKEWhJ zVV_(TQ2eDfBcU=`Ac7;bNk?*{~u4k z`^TvpKYQ<|XFvMu(Wid?m9PCuG>q?j=P%A4JX`+st@WS&4k5nddvBjS`S9q2x7YXI z5ltoepeRdr*LN-Hn9vttXl)BZT5zkWTQ@I>$v_$gik^-`hb|o0@c<&GRoO0&a-wsMo#M{Zb;CFqqcnXhw(I}DUcCpL2@8v=DLRw6p-+FMq=f0o zy6QG(W#rk@-7sI&YFoqeqINrb;0604-u3BrIb4cH(ViGKg-<%-6c#<+K33c}aoF&I zTg0Nb0Cd=$Tl6Eb{fZlF@gpa}rJ%0-ah&W;JS@}${q}-E{MVS?0!bUYRgG)cL1fUM z#qbt9o+#Y|!ShB4#AH~cw76KL^CMqYgtR0#oc*0^lPf!Ptf05!QATXlwrq=PX^QG0AzE~@>4Nx! zaBzJl@qU@8D##+S?hqIGD1y=nZW=rxrUboVQ<5Z@F@Smr^C2b+gm?>O+(9xrm=e0B zAA@Ntq_w+V!4g^%I7Hl2A&PHQmY%OK=J__K&l)8}9C! z0Q!a3t_HgY-lAX$5*$#J`#c%3v6rIDLJZRLq3AAWo^UKor6j2Zam&b@SE`BtSK9j6ekIWpB+X(BW>W<{!6t<&=F|HkdFe*5ru z?>stPs@XWe!X*Y1;hN%)q#Fn~z$%s_>2=^z$Cro_h_=$aiVrw)@qT&omlb6%ilM*p z?fr*Q`J*SrSPZOGwC6@_?9H(vfT{;Rj1UL0>}1S#nidrm}j#ZOvj*w9;-y;rhf9at<1)jU<& zvR&hJEa^HD;J%W?CpDP1jg-S8mxhlE`GcoJr-+K(v!*>uk9vddT4qUyAX zr(OvoEN66(WLs;!YRa&U3pycc?raJF6(Y%9&&dbSffX%mqUbA!_GB1c_hO0*XOuf5 ztNs6Zdb6HOvg=ALB2LWH9lm+Wv9jhWai&O7l*n$;gk(t#wcP?_2(V$JpZquc;%7e? zHef#(XiE(=EVo(`)K*h!QB+gnD3VpIs+^~9yx+Yy=7=-I@m}Yqx>Tx4W@YAgzld}8 zUVHDg*9xdGQGCFbss$fhg+dKM*aB~ZBJLnPHAbG>mfZ9}@OkM&he0T%usr)dzaTj7Lo!?kShAY`AKrq|rA2fG+# z%2d+|iWhL72^hAuiq10g70Lz}hlr6oylGWqW{*zndH>^Y+?(hA-~Gu4^5Yj) zU(sj&i@$pKZ~pWr-~Zl&p{W1#KR)`)$BTG7DkWC>nzFoiG{3lz&xGE)JyTZjnmbli z`(V&F-Z^~B4ZriWIC{^YO%xx408M@+UAtNjix=hMd{wU7hBDD*!P_1kN7!HjE>XhQ z#?S!Z$#X3V$7t6GlX7e$cgStRQqZB2bVexwS;h6pDKE3gbUf)KKu^}_EgH@@=Ip74 z+NozeY{Z7hY*{NlUJd?7FJ;|~rZx*k>}-3|Vsr}{=2?4p?Jx_%oQZM1b#UjM&(hT_ zPG2^4&4hxTS{PaI;{yeX^G1r6aD6L3z1CVcax%9kS=cQ(jF5A$8Rb5K=0V59=xvR~(puK?7qaL@ZG~G?sGERL z=4^tN5@P#>fA;aXK;v2Q#;$l@3o0Kq`n1M<2wE{= zmPT2Y%x07MEYFgdP&-nT>-YiKrJM`8j8sKYK=)vf41sUQ7;ecPGAOPe7ytnNF(lfs z4Z877gWaJSU2OL1v`5u8b~3$)QfxN$qDXY`IVNaA7oHi-lA#?C*ZHuq$c#bhHiS3) zO=l6)q0vP44QYb&cIfEuy6*s0K&ro*zG->e(ANs5Q$LOgeOVaKS{wgp>?P3g4I?8s zIZ~wy`y&cW_+z0Z;6D4o_sX*u#RuQ1e*X7rx-;@84Ei{fFk_TAO8w$*{2E1$AN`;I z`%qk1q2=uDT1OKP#zt}Yi?_XH)jhrfxC=qBww8tZ`D3f<0ZfI_`!r_Ys5uGqG!3jZ z9J-WJ(JQMPEw#5jS7ljMtKL={X8{PwSxoxQB(drRRj)csu(Q_}qiT4$)_1;fXT2Qj zYt^r->hZZ)HeQk<1}O-azH%9br`HH0PNPRjPzl=rLil0mKwL~>Spn;mXsQ{TPNrWm zry4(AhtPzjYwk+nEzf{{CaITCy!B<%t~w>{VNBh0-}3@P&Dd-oFwF!EbrgMi(*nX1 zG1PcN72o_l8X*=4kyvIqZ^QINz&F3jtRM?C$p@F7!0wJ4M;k*iW3`2T*QTH}j!o!% z(_i%6$C+!8uCWpbJoM{fqr-V!LW9l?c`K{S3*Hpjghc@+tV1ol=~1#hQ)0lM<#=Hl z`#8`8CJ7uqcNht|fiji{dgBRzP5>6)#}2~BeiWHgYZPfQ7&2{o>>S!SV=jo^R0hyt zFv^F<;D8=`&^2@Z*>C^$ zPk!{{AN=UYA$kj*9PL3UC-HaZQx6K&=v`?e?}8hM(#WWIZHR!zHmdLXtE(4E^z-YiS|!Sgan+MNU6%c6nv?>xT_ z?Yvrz_f8JhVm)=^B%J(+^0Z{lvKgE1@?yPnZ+iLdOT=g|`j6jTz4dF^{ZqQA>~NN} zYtDwglIqFBVtb@}rk0<(9e@3s$^ZR>50{0=5@&2AyJl$)wP5Hl#c&<lYQLe0)U00~*-)g|*VtTe8egEU?<3C$kjrFKpSR4(Y*l)#pSrMQi3C$ zbqd62jR6UY@I-}FMFt*HiIKsyLd`*{w!9E@Wj}N#6F2gVs8OvagjQp{tOsR8xUioB zw_l8|6bDx;oieOV2}^RD`&eVQjDPcP9u)M+T~A^yRzVUja?FaCEioyAk=ZNfIcp=q zW#-4`DoLwnx(BaaSEkn&I%BHc)C$6}5prEeOh969KTeq$y{WWbFWXaSI#{vAdz=Pm zzyRAw*#oeIX%KElc3@Ljai#~lZ+TBSjtZI%gLU5wP0Ly~riZ*~w%Aw+l}vQDN)D2G z-G&pVr8mb35vl8|x-R?qp1*%P%Xa)~t&25A>hwsJ9-!MUoVIA`!g{6KYG_yoJHnljo5F?ZYFFd{cwLQd$l zy$J}=YoG(fgp&)+9aY(z$tcCf zqBwUHlJG_yqg48jzJ2;DCw(QB5B1LD|M%h7-)Vo|THn8_2)jJ8*%v-{BtN>ov7Nh- zU#n(zGC4it&pN&L`c~7+lhC=F$AA9gbv)bpl;c1AxKaDj&O~)r?fLV5CE3xQf3g*Q z@RE`Wctlo5*HHl@_8`rwt;7jK-SqSrp?0@1%OV^@QFYX27zI5R`jr7Qa;B<*MRHsn+w=&3o@bKXG+2 z%HEGdOvQts6FptBboXeaB)GbSyOV_6J2!G_Nx~La{On5Z?+-hf`{G$sZZiSuxO@J* z+l@kXU!RERZ`bR)v-}sg0&*h$u~j=u zZF8vCLiGUDc;2sl3R$j^=rZ4w!el|A_lGq=^-Ayt0M%>-7;XZaPph&vSY=c|n+pFN zaVTv}7X)PiScC|4{5SrOn8Ue{NMSOc7mq%Y>t*)#=XQVjmuK(1pPjr$_vQ7k|MKz4 z-e|XWk_{K-w>!>yQ2@m zSR^9P`0iL{`OA2t8FG_p6nR*dM!O#inMOqhK?NttcBsl68W6bsJky>>@R4c_-vbyP zO{s{5XdgV8zA7nHR^fsxKMt#8Zd zxPwr)*}A0GsZX?j~l1gSB@s* z#jred*H^{}=dVPNF z1u~k#m&2&Y>5bAm6%{Z$Fl)hPivYKCo=4f#O}zUbT=pZCBptmdc;IMf(7dy{ z#%_HDkpYV1hOURZ)+sBp)W7__!|yK6R(uR2du;S4->ZN4SKUWH92Sq%cJ5{So{`74 z2@=sqP3C@E@DUP_Fg2`BK~K5=@5=QvL12j~<912(JrycF~qqzbd+vpaZ>ssf|kPNY9^6`;A$;J4<%ALjrkKE3qu& z*n=Jmo2~1iyr|)y!!^}(VF=fRbT`lU4;*XD58w2n)O91s><*V&wzh^pln1dV*0qq0 zI6j&jrKvO;1_Nac4bLVJ<0(o)#l@%F54lnc`KDS^ydP~J#C}5fR9j5vcAOHb9{pfE znX@EyVBf1$hiGa+*Axd4=4n_p%AEPcrT9X4NtE^{fNc0z@4QSVO0W}O$*eJUh2hrRB{IB^i@K3 z(yY+H0UeBSSF>#_$EGJqJd5*rsz-V8eBBNrNxZ{b+48!_BeirG`}q{S_On&Pl{~xb z`(9nWX!=@|vA`Ug9vJk#mn6?BpIzoEeiI+p-4n}!>M|mBloDOv7vgstAW$4TG!XR4a zQN>QEopP%*P9N9=3no<1w)|z$PNSH9n@68f^6S0}SCb;7vbS^7C^1{r~FCtH{jCFTCTKmT{ zy3ea|d~GM0MKOxSPIQa*yHDDkclIc5-gKlRslyAPar_RftNin+-wkzJO zEsV;e;NW0Jhq+ibw{AO&OR!a4=Awe3qZ0Z~nt*mfNMq;;m1C$xRUPMMEod}jWnqCv zrRd&U;gpWA2e%8fW~Pb1mHAY$qG7KgTG}fr2vyF;$kOz8?#jfLXtsloLTM@18dh2G z*RVCy*vMGB^gS{}sR0R=ozx!^1*2nDGyqL7WrqUeCU z6+WQ_b7`ht5s}fg-LOM3fpL6^GLcZ}V4PvhmLz=_1N~mAkHL(`Z8rjG`0eH!_q||e zd*+3eX^dxf8pavwZ?T%nd1NbycGXrB(FZ%OG~upa`3Usk>VBU5kB* zEMtVA2!)nw6=-Y86n9vEDRu2!P_7a3jlFaznhPhK&ZF&I&!%iX3-|71@BTBb4~Em1 zVkPACc9LyRCi(U}+CghMVxb?|uH{j2JM_Zp9HV)xaKswyqr$Urgf%ABCMBgdDlDN9 z1J25zvLuAF6?9SE4j*%%Y9_E)68UuUft8roRNVKNK$n3n>-ws!%eHN+k`i3s_TA9C zu-c}eI$;0StS6gv59*7HRti0to&|8q8UbR(MorbD1JLztQPNK)^PIjY{NW%3W1J>2SOvRH!^0k}7f9KR!gwiZ&#@yoMFGbJ z4xw5jv3@a$vA?0@tqO+qJ6yRsi2 zUD%Cu;>fOgyBE$EZrQi@>0+vWU^^54)3@Ev+_XDkEh`myI)sUn9ykGWJA@3D)xtz` zSX>Ro0y79Kj#G|e@aJJ5B+Tc*{5az6h+bbS`eyWZPh_W?vrE}jUO+L)m)Pha6al+N z^e>GxFdDZYY2hG|C{frn&Kk=82>wExG$KzNS8wq&frYL>Trw>?1mj;z_}R(XuF1rf$bX( z89oh46=&oAqZCB}St-6s6SceTJBmu6Zg1bqVtB^UVFOVEibO8eySAvKjAgqy3sKo` zXe~w)c2mxQ8PXNa+5MNr#iiw`AaeG$gWb6gP9Bxj^k*frd^Q=)iri+U0+1S%K4qj2 z;g{+~9#zJQs!Og$0z=kj$$8{0E**IAhA%=tFxSQ09%BcJM&w4E$2LV2Jrzul!K8ty zp$F!-WmePuP+5&NR=;&F>61{z7_@2P7~LBWHL>9yV8V@MR{EOsqF9WrS$ja{hhDw# zbnlprT`Fe4{Kl(SI*dS$kzDi;xC_DLjIeQT=)|alpuH2(dBj`4s#jm-Fz~! zlEGKii@IEh-Vq3C@N*vXJ!^WyU3LW~Ek56yW_^wI8^R{TV14P$boQ?Oy$@Dt9{3qH zJwE(azr2LR#iEoKAM)c}f6N`xE06^N{*0QjvBJhJAI8(amzO{5WvB#IJ-vNyEoOV- zi=W&1mCx?~=G(U(Jg&3X{onX+Z`_scXFoNiqx$f)YaS18CZ4?Ee*8&QuluHH^I1X< zczxNu*%<8DY|C-Nn1zuALa5u-!{U56 zdVSuNqF8j*T3#*tWh0{4CwP9gY%hy}a%Hm~2|8kt&$nx;^zj&mwZj_Ap*oSkqmYDi zqt5N=?5$N!`6zba*s?#hcM??6&zG*y9@R;@lGve3y#1RLQk~U#M=%t-?0E?0E2YEG zM>n+-@S_ZY?VxA}sy7IRzUx!@k?zgwim;Q#qR8_djlEEmNfe;yx)D%2+)fC%m!@0t z-gb5?p3kgY^!#*P?#Hl}4B1xW@C#WF6~$WR1hzkSSjfPlr8G+~C#4u@TR!IfzK%Q9 zXu`rEB|5DVPpB9#**D)iIsf~Im(0CAiyyo!yje=IvA66+FZZVTd>Zktd-Qx&x?Xma z)5W>T`=V~Y^R$_q?9VuVpxyY5xn0#=p`B^?#@q3y--z!&<%{z*g}kD+M?17ZK!`2y zKjxHNp|g9o&{btp;^;ITNQwetWC3BJwx|E)jU(M43e}QVu4v*24S;E6M}b!n=(aG` zCJam`;+?s5JLHEB-*VL!LGgq|pczxx9=yQz=zficOM|L_-oDp`+j@iS!rY3t6^q8M zB9IHBgchOlBegelSCkwAFVjXyor;Y%j2wa;d@%BBdZSB*p)ls|l;I$(2xAa|jYc%D zTwfWZBH)cdZo04NY1@JAn2QP(aC8+RXh0zWJE$yhF2vD&}(q&w9EgghKm93?0_X(y24?eJbZ>+u`IOtO+lzDcO$m zyD$se4dRcVH~-CV-F>-kxECgIIM1xN@ifoodKC~5A30M4 zd{woe{K(8GBXA@=W<}RoP-JQ4(DWVMwMKxV%q3ki9YJ``P8&PW?ilXwn5`cSVaAj) zI0bfL(;We_7icEd^)PCOOCx`&Fu(?6F#d2D-Ha*-K}w;TWg}H<|D$jw#3_={js3op zAW$)YDLPahxCRcqZfwJkVXiW;$IQv0n~uFuur!pxY>>Qw`<+s4*GM7UFwCYiqnSsz zJCtT%BJnszkP0ClO2vTd8kY>u4dBZNasz?{*uO@~a%0icVAa7f3ek2jN&Gk=!~$*? zz8dCl^n0;fYB)K@^2;dZ8mm>LZ+7#oeEY`D_ddH^ovj{zQmxnY>n4+ou)^tsr!PMG zWO{Va6~)`%{6_NHTMc32$ja{=P~7UyR}@beLEC9$&64rDvI5t+y{&4FsLHvWhnm27 z*IRNFeXqAu9lCZmpk}4#xLRAM=OG0Vm$hf7va2aRDO2OvuCWxcY(Mah?!@%bt1F&T z*sUmkW-O%AaE&f)7@Ls_RoL*wLUJ;?NEmKFxfD#Lp{1`b!zkRyJ8UEvVJ6FaV}5A# zc}zPNs#QZl0Ae&PqhEM;a&njw%DHy`7VHhZpk^cc!$p_<8jjH8Jjp&VzVPjH(t4dG4Vx6@orrgpRyg!5!;H`zXj z_YdO8AJ@wwU}Bn#p4}&b^2b&*Wi*MxX$-0?rYKPVR-1mW;m=Y@vVM8Be10x?gDTU3 z#6%uDbWtc7Q#oF)EY)Ec;)Sr|;-KPzBWR#DM1<-7_{`oE6_gV^;}{A#DzglR)*zuX z&(qdF>M_GzWU~%38mgXU++6_FUE>J*ipCG`75tf4FRVJ3s*cgFA1_qPA)H3%>v$`e z$MCod{BSGIPqzF#rl=`6xMU26+d48s&_> z?pNoF@^Y#85M)*~Lv^S-BTz42Nlk9VY#ieVyLp4CdPk%A3jJtw!l+)hrxY6*CWh!i zj>b2^NPoe>+bF)eHo`Sm5Xdu*z&2fKP>q=8Y-p* z(K3;&Z@Ru}gRsx0d~)dYE2c_GFGeUPTBbOjSy4BtcSjBxrO_X2>}@~`xRuS#+gle8 zuDe=aD9QoWahlOXDXS(-owAmf=W^#}m~SPN4W=zy{Ph((Nyo%``jhi7-??q^@k(^` z06u?j7Txk6U0?aRJ~+&7olFU~0eh>o@eh;QZm*xzvlc z`|6jD|Cc}i+38)G96QZQuh-*#$nL$J{>?{M`?qEeqJl-KrRuml@t?lDrgwK)^NYHF z^x|q&HJ7zWd;-z*-0W6btq=+2>y_#nKCC$bcQ5v34;=tOnBx3ma(Jh@ezAP?U8j3) z%fTPfLF_CS&Pfe#gq>^$*-m(M-aS4mwk8oXE~KHyno4l9dPo_Ku}j^ES~*6lVx#u5p{QBL7ZzeUU>ZpD8nBy%p*Pd7s$;IK*0L)_ zM`o-X78|1_>G*APURo*%w(VYBgg3EyCpcz^(Ox?AS}g~kB5CAap^8!cD@^2oHp0XE}t^FhA#D@ z<=4f~_bQ)8TeDbpdKevu9x%JNbkN7PV6{z;-?L42^)=mTh{bVi&tnPQw^cH6?%s*A zgg(0;8S!cghr^=xW`Vz(cxf=(qJKE6rO=pQ;6G!=Zrn8qPK#DWNr2@XlpiiEnYloN zSvx_Jp!+w?7Zu@3n2vxBq|u6kC1wz?gi3o>Eov4)lJdpXnqcK|vbFC|9p$cu@r~_$ z?dIopKXz0Tge+4OP(VL~GK?W&~wOD63!7vGVzY9&D3|+L)s~cL?4X`^uiPY~L^&x=^Sf+Rsr71iJ zTSq=xcroQtdz`q#JRBUz8&fQ#LUtc{FU;*AX)eyX>vfiphl1oI0Rf%%(QEc`+*%XW+`KG0?0;(EyU~y z=6$9wL8pdZI5Tq61ShmRRC=hyz-8ZwW>t>$s5&KOCwOHW2^s>KeYv(rHd2BlRLFc~ zLngtu`!Mr4WmVhhTABHT(U=t_T`zWz!lD`y%bVN^@_lywtYey0?dT`gZ+u)F{h!Ip*s^KzMCm4Y4X{Qr^Bjh&lW}1_DopwH~_d1It)Fm<8!FKQS?I$+Q{Zw zR*wl3*!Sk5BO0&(;JE8Lqtme&Z~%1y@I(=1l&iSjMx10^# zQAt2<2Im#SlCF6W0&iV*@1291bF`SoUg-#fkg?ED$FQqF-CNV zY_Dz9@ie`8xV^tWy;?X>&h24pLa=r8pabDk2GDR2KpWn$pf?EBGGdOs=*%XWC&yyG z6FEAK>5Ot48w+jKcUO~yAMLtX0-#^_a%jcHvMU=-N&Uq|`TXTt;IX*7`~J}(#rn3s zUdy^^mSwrDs_Uv*6!l_7B?^NkvkeroD2lUl-qdKV7$+w9!un1cxtGO2IIt-x*u{jz zOUh;hk*G$Bd^ZjU3eO$)1IIH|6^7L{WdxkjgT%UejKw#s+GAhUf!afe&lknj)xb-vGx*w$MlW#2 z+L**Kxsky$N;$^dZ9`!)6&ISjqp{4wTh+-Vj8exBDFMJk6QP3+)?mEZ4S)gYC#dfm zZox*z6)WPQuM_MoNZ|SGIL?k!EO%=YQYh`m7*^mT`o=z(w)6rhVY3LgQzdLr`hT9$_?$~!|Ax_mULih%Tf0B z;cWNjbnmsvvyYaPLMK-18@A<>@0~w;zTW%H&fd+*i8t>GPC#=}S9Er6@1;$wu8Q_} zK8F=d5vp!RhXj19Uj4%7Grc`F+EvEEIok0jC*i>zy1CBT{SK=DOl-aH@{AF{XjcL@ z2$=tZMEK#KEPwn*=k!Rapc1V<*<-)|`zIfl<^S{J=j*NDOsVUlI~sNy9{kelJLk8@ z=yvq@NA>!nwyjkb`CtC(_RlEsj95`krqN_8tE%qes%2C?Q^5ntbPu8yo|hz1)zX7w zk>}2sb8DW}?fBxnuzl2QLxDwRs+bj(JgWwY*%Pa0_apk|*KKU`uAzc}@Q)y5(HEkH zrK~+jdwtgD2mbMNLWg4A4W8@PYxtsXO|xD4|1@rgD$PCmtLX$NI&=_yvEpNmqoN^T z;An#HK4z{?)r#HR^Pzl8uilDN=rDCHv|%wjL#rNV)hOXoinolp5=K~?J$Lk3EVB#l zfUsb0rx~q5IUP%`Ll16c)jC}d`WxC;%6P0guSmJ{2MzS!tln`ua1sc`Q(8hprI4~1 z9pTMN$zC`K$fN^-E$OwLRThKi^DtLq30I}A9kyP(HMx7IUtCa@3yiIe8sL?{GLMB` z-#`ym7;+*8np6O1Hp@NRj_6ZR;2L{CnxVA@C=N+K^uxgII=Vv+U4(Y9C}ML6}*6I|O;&E(%Im$^L9Q zi)^gHIRp$W)0FXozzU(?#hb3Gu`koM!$ncq!EiLsxAOhn>7iniHGOxob3_{KMw5wM zR9%nJR?Nn**JWP`tAc0=eI|NgiJn0I1o^UG4Ubr~=Z9NIzI=Fje&_Diubu3E^mP5% zH}^a>E);g+(9Tfmb8noSo?e|@HDx8z-HZaMop|}}`OfW$XojtW@w2bjTVb7LV~|dC z3&Cx=)w*jSE8gKX|b6S|xIslfj>iM5Szx1S(uT=R6Ys) zDKoP?3FS_kQX3`w9@1JWrQZ~wg!2N%F>*3wSv1G2&XDi1@cEAoM0B|V!Yw_B^Z*<9 z%SY^>co_Og(02_5HOmMrgBax-AgT>L(b>3m;jM6~AnFDE0MS&HO$EEb&bpU*6jNRv z2O)dj76osbjr>;-Q5p>`H`IPWfYtGb>COPInFhQWBa`)}g3vayr>6<49 z+08w1`SRpbpXx5o&i?ZM8;j!o-~KK7QUtl4|GPh?@BZSi{)DgFzF!4*kDNGh_UB_+ z$W_G*XT*wpRW+KfRMWzAk$~4M)1kXr<6~C^yIA81nzbTllGt~SMVj^(i~jlo=sO?? zsJCAmZ@rar=|zb<$>7;oEe1#G{iE>3Gpcz~&!dCs6Cj3!t$}KI{AN?ryaF2(f5O^A z1~FkfNa0$>%hv)un@$+I^gwEkv*DKzdLG9rj_Fxb&B`O+I=-DWgYJY@Eo)Z8Td&Q_ zwfo@F`1}++253c%9L}c!RlJ@jeP`nWYYKsl1Fiv*_$x>WM%EUqF`cz!5HPI8Dp{@; zmR#;k_op9Wp3bQ{tz9$g7s% zyPz-Rx$z{Tve+`)pje@GY}bdPD*a}xyGi;MC}jpgO2riwM^sp%p&kce5{2mR*=i$- z<6t`%nudhJH;zafdnDKJ{-F}%x&9>59-s{R451gyW60+E=9U_>V#ATQq_C(a(4I?| zhj4S0MMG6LS0EXCk^i4r>PBeVd}ZHtsa{$)7tb$>#ic!RKQk>5_)R-3U<7vHaOR7R zlEcR2*icfe&AbF%H<%pYl6&;6NAyS1@A5qlAKQ(XaiWwy19{fQbOK?^OcX3EIAA)4 zsojQApf|f4fno7(MVqD)hGH;4*i;-K*w9a=StJN*3;1bk!>pk)tiEjhQQbaH-@LbV zbdZMVK0%kC!b*MJpiDWio|flj(Y`_Rnug)+ojpsZbXD4Z%(7HNaGEOG zkV${A_@Z43&XURa)nCmBm{FdiDzjcw-O!EBIG<0V)Vp(hB(K}HfLLcV@h7w7;g3%r z{_K(<3w^iqcXm!6wr3x$-uSg!$8Ybq-z#7K_-e`P#~mhff$dFP=g!IWQMC*`deza` zxqV@503Fy~T$~PXZTabzQ!DUJwPy=H7U$}NKQFKwEyd0O`^9e@OftVOurrwKM(Iw_ zoXa2lUyF~wyKsCva6<~`w+`I@`givK)!%&h7mv>FytDuE2WQRm!fJybe(Ul#zj(0y zjjj7h9|Zohe_gbvVqJ^(UJJMHdjIgW@-^$Lp;$Ft4PD`Bn%p>^(+e%uU9aT!Jl&n9 zi|ev%Bo(QB%jtH0bg_Q6EZoS1oECvZ!P^moKF7o!UNy08rqmUt0aS?N0(&dG@MX54`JxNJKkMvmRH^B-Y*QrYj0;@fN&VHsy7DebF?n3TF}3 zXys~<7T7`q9y{vh05-QHc08zBWWE}#%ZH_C)oM-gnJrhty4LgENN{!WQn-m-4{E&} z7fW?nh;qfN3a)YrhD&BwRJsJ>>BIL7x?quZA@sKy$Jy5Y9^q%VXuY4k7~9^8a+gZC zmruK)fKc>ihszB-!)kLh#d*4*!)C9^K}X4GhH1D*urT)e8hT%{74-Q047)nvEIWU8 z?YY+W$v$C@0GsaU7gG3kqY$x}Lw~1ibsl?!GbmIR5hI8-xjmii$4{3R7u7|^o7}3d zEUqu&x}#r{Mc$Es_(i3-F;eY~XT0bGJJEoFV$iL!1;v}sAG6oy<0s4Prx#rpW|Mh( zT8qNM1}A-UT&crp^2_fWJ~_R5^t|k(O!ty-5>2Q`*p2N0ju3|jGGuL@JIOTI+MQjk z?T7cNwrQuc!?x@(G4m3-II63d7ePh{LS1a+6paRmk(qHRSP>f)MHHvdOp9X=9W{y5 zKbf<-0Wb>uu$K{GMZ!u`Tjril*!bl`_LVzsQ)pLOhbb1&s$NY)Ydfa<7TB8cwr_-2 zYiJ?wzxDaqt@ozeHfpIp{w+~Vk_x~}p= zw{2KmVopW5xaZJCLe67=X!Py?3PX!-?}qJcZ<<4%W5JKW7!5G+WI$LmL;ykIIduF0 zrH!P*m|3jXtbmIjNa>VQv~~x@DvO>p8>yNZ>DLI1!xdq0r*<)+45$K4!^RmUA%{41 zAtTg@bm~V3$tcHww>}FittUHsOp0P-8TpAvRxy-2XYr5{`FESX@H#f!%<8|ax4;6a+SawaE$SxiBg z9zp|j-Bzv@F%1C;fyW{#r=pPz6HZ4^T|bNje?7=iAiPk$KuN)LrSX7!&K;vXNp~zF z%n^riOg9B&=`f6g5u2ytgHi}5kh ztLul9ju$;C&rRsxE@+w-#Z|`^O3ilmv#nh(OoJezf~xJgHk^GzpOGIzD+DOrQG$D> zV1a#+hpjSZL7u#VjFO6MBdE>!PPQEe5&Z%m9s*RV_+VwDY(UFSIwTBxdwuf`FZXrz<_CtHQ22!)Cy^)4O-V z-oN4A+L2A$Jbr|sE1_E03y#wrKS@1%wBitjT5&G6w}U8V&+gk!m{QS%XAByqLPJEG zO+tfG(d*@$x1B|aFN|N&q0A~O6uu>%)yAFIAa+JS!J9R+t2ok(@F5d2(#aM$C)cN= z9&~Z7Z{67TJ^ydM+cX`+D9mU8Du)s(70WTKfvs1JXmbN09%1bKjAEmOs)5Tc&Q#yG zlxp&6*j6nc);oL7$zd?bD8B2bm+Q-AiwtZiTFUro8cznxY%thc+bLZ?(T&Brg##J( z6fqeZxaxZ82F$PzjOx)SwXvZv5-bK0VlNt^x3>>MⅇTvRZp_oS08&4lq^yj8SYK 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 z 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