├── .gitignore
├── .idea
├── compiler.xml
├── copyright
│ └── profiles_settings.xml
├── gradle.xml
├── misc.xml
├── modules.xml
└── runConfigurations.xml
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── drawn
│ │ └── lltvcn
│ │ └── com
│ │ └── textdemo
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── assets
│ │ ├── res.zip
│ │ └── ttf
│ │ │ ├── 01方正经黑简体.TTF
│ │ │ ├── 02方正静蕾体.TTF
│ │ │ ├── 03方正兰亭纤黑简体.ttf
│ │ │ ├── 04汉仪铸字童年体.ttf
│ │ │ ├── 05汉仪乐喵字体.ttf
│ │ │ ├── 06汉仪良品线简5.0.ttf
│ │ │ ├── 07兰亭特黑简.TTF
│ │ │ ├── 08华康娃娃体W5.TTF
│ │ │ ├── 09造字工房朗倩.ttf
│ │ │ ├── 10新蒂下午茶体.ttf
│ │ │ ├── 11迷你汉真广标.ttf
│ │ │ ├── 12方正咆哮体.TTF
│ │ │ ├── 13造字工房静黑.ttf
│ │ │ ├── 14钱氏字体.ttf
│ │ │ ├── 15华康海报体.ttf
│ │ │ ├── 16Aa小鹿.ttf
│ │ │ ├── 17腾祥麦黑简.ttf
│ │ │ ├── 18汉仪乐体.ttf
│ │ │ ├── 19华康翩翩体.ttf
│ │ │ ├── 20张海山锐线体2.0.ttf
│ │ │ └── 21新蒂黑板报底字体.ttf
│ ├── java
│ │ └── drawn
│ │ │ └── lltvcn
│ │ │ └── com
│ │ │ ├── span
│ │ │ ├── BaseSpan.java
│ │ │ ├── ClipTxtSpan.java
│ │ │ ├── LightSpan.java
│ │ │ ├── LineColorSpan.java
│ │ │ ├── LineImgSpan.java
│ │ │ ├── OffsetTxtSpan.java
│ │ │ ├── RandomBgSpan.java
│ │ │ ├── ShaderShadowSpan.java
│ │ │ ├── ShakeTxtSpan.java
│ │ │ ├── SingleTxtBgSpan.java
│ │ │ ├── SingleTxtRotateSpan.java
│ │ │ ├── StokeTxtSpan.java
│ │ │ └── TxtSpan.java
│ │ │ ├── textdemo
│ │ │ ├── CodeActivity.java
│ │ │ ├── DemoActivity.java
│ │ │ ├── EditActivity.java
│ │ │ ├── ListActivity.java
│ │ │ ├── MainActivity.java
│ │ │ ├── MainApplication.java
│ │ │ ├── ParamProvider.java
│ │ │ ├── ParamProviderImpl.java
│ │ │ ├── ReviewActivity.java
│ │ │ ├── ReviewAniActivity.java
│ │ │ ├── TxtShader2.java
│ │ │ ├── TxtShader2Ext.java
│ │ │ ├── controller
│ │ │ │ ├── AddLayerViewController.java
│ │ │ │ ├── EditParamViewController.java
│ │ │ │ ├── EditTxtController.java
│ │ │ │ └── SelectController.java
│ │ │ └── data
│ │ │ │ ├── BgData.java
│ │ │ │ ├── FontData.java
│ │ │ │ └── FontStyleData.java
│ │ │ └── util
│ │ │ ├── FileUtil.java
│ │ │ ├── FontUtil.java
│ │ │ ├── SUtil.java
│ │ │ └── ZipUtil.java
│ └── res
│ │ ├── drawable-xhdpi
│ │ ├── f.png
│ │ ├── fore.png
│ │ ├── jjj.9.png
│ │ ├── line.png
│ │ ├── line_bottom.png
│ │ ├── paint.png
│ │ ├── paint3.png
│ │ ├── shader.png
│ │ └── timg_4.jpg
│ │ ├── layout
│ │ ├── activity_demo.xml
│ │ ├── activity_main.xml
│ │ ├── item_array.xml
│ │ ├── item_ck.xml
│ │ ├── item_demo.xml
│ │ ├── item_enum.xml
│ │ ├── item_layer.xml
│ │ ├── item_normal.xml
│ │ ├── layout_add_layer.xml
│ │ ├── layout_code.xml
│ │ ├── layout_edit.xml
│ │ ├── layout_edit_txt.xml
│ │ ├── layout_edit_v2.xml
│ │ ├── layout_general_layer.xml
│ │ ├── layout_list.xml
│ │ ├── layout_review.xml
│ │ ├── layout_review_ani.xml
│ │ └── layout_scroll.xml
│ │ ├── mipmap-hdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-mdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxxhdpi
│ │ └── ic_launcher.png
│ │ ├── values-w820dp
│ │ └── dimens.xml
│ │ └── values
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── drawn
│ └── lltvcn
│ └── com
│ └── textdemo
│ └── ExampleUnitTest.java
├── build.gradle
├── freefont
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── lltvcn
│ │ └── freefont
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── lltvcn
│ │ │ └── freefont
│ │ │ └── core
│ │ │ ├── animation
│ │ │ ├── A.java
│ │ │ ├── Animation2IA.java
│ │ │ ├── AnimationQueen.java
│ │ │ ├── BaseAnimation.java
│ │ │ ├── BaseAnimation2IA.java
│ │ │ ├── ICanvasTransform.java
│ │ │ ├── TA.java
│ │ │ ├── TAnimation.java
│ │ │ ├── TAnimationQueen.java
│ │ │ └── TAnimationSet.java
│ │ │ ├── annotation
│ │ │ ├── Description.java
│ │ │ ├── Font.java
│ │ │ └── Img.java
│ │ │ ├── data
│ │ │ ├── AniData.java
│ │ │ ├── BlurParam.java
│ │ │ ├── ClipParam.java
│ │ │ ├── DrawData.java
│ │ │ ├── IDispatchDraw.java
│ │ │ ├── IShaderData.java
│ │ │ ├── IndexParam.java
│ │ │ ├── LayerData.java
│ │ │ ├── LineData.java
│ │ │ ├── OffsetParam.java
│ │ │ ├── ShadeRadiusParam.java
│ │ │ ├── ShaderBitmapParam.java
│ │ │ ├── ShaderLinearParam.java
│ │ │ ├── ShaderParam.java
│ │ │ ├── ShaderSweepParam.java
│ │ │ ├── ShadowParam.java
│ │ │ └── StokeParam.java
│ │ │ ├── layer
│ │ │ ├── BaseLayer.java
│ │ │ ├── ClipDrawer.java
│ │ │ ├── DrawDiapatcher.java
│ │ │ ├── FontStyle.java
│ │ │ ├── ILayer.java
│ │ │ ├── ImgLayer.java
│ │ │ ├── LayerDataFactory.java
│ │ │ ├── LayerSpan.java
│ │ │ ├── MultiLayer.java
│ │ │ ├── OffsetDrawer.java
│ │ │ ├── PaintHandler.java
│ │ │ ├── SingleWarpSpan.java
│ │ │ ├── SourceLoader.java
│ │ │ └── TxtLayer.java
│ │ │ ├── linedrawer
│ │ │ ├── BackgroundDrawer.java
│ │ │ ├── ForegroundDrawer.java
│ │ │ ├── Gravity.java
│ │ │ ├── LineDrawer.java
│ │ │ ├── LineImgBackgroundDrawer.java
│ │ │ ├── LineImgDrawer.java
│ │ │ └── LineImgForegroundDrawer.java
│ │ │ ├── util
│ │ │ └── CU.java
│ │ │ └── view
│ │ │ ├── STextView.java
│ │ │ ├── ShadeEditText.java
│ │ │ └── ShadeTextView.java
│ └── res
│ │ └── values
│ │ └── strings.xml
│ └── test
│ └── java
│ └── com
│ └── lltvcn
│ └── freefont
│ └── ExampleUnitTest.java
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── res
└── res.gif
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
18 |
19 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | 1.8
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # FreeText
2 | >Android 字体 文字 特效 动画效果库
3 |
4 | ## freefont库 功能简介:
5 | >1.该库是基于TextView中Spnned等接口扩展,实现的单个文字特效,整段文字的特效,并且拥有动画框架可实现单个文字以及段落文字的动画效果。
6 | >2.单个文字特效,整段特效,动画分别是三个框架,可以在框架的基础或思路上扩展各种特效。
7 | >3.不仅可以通过代码实现多种文字特效,并且支持把特效转化为持久化的数据,集成库的app只需要加载特效数据就可以显示特效。
8 | >4.文字特效兼容性比较好,基本不影响TextView其他功能,可以任意切换字体,字号,颜色,添加各种spnne
9 |
10 | ## Demo功能简介:
11 | >1.demo最强大的莫过于创建字体特效功能,通过创建界面,可以手动编辑出各种文字特效。(注:该功能还不够严谨,存在bug甚至崩溃,但不影响生成的特效数据正确性。)
12 | >2.demo集成了一部分示例文字特效,可以通过预览界面预览。
13 | >3.freeText库目前只通过代码实现了几种动画,可以通过预览动画节目观看效果。(注:时间问题库暂时还不支持数据驱动动画,需要的同学可以自行扩展)。
14 |
15 | ## 以下仅仅是示例,运用动画和特效框架可以得到任何你想要的效果
16 | 
17 |
18 |
19 | ## 集成说明
20 | >暂不支持jcenter,直接把freefont库作为model即可。
21 | >具体使用流程:
22 | >>步骤1:由于有些api不支持硬件加速,建议xml文件中要取消硬件加速,如果想用硬件加速,可以通过修改源码解决兼容性问题
23 | ```
24 | ``` android:layerType="software"/>```
25 | >>步骤2:代码中只需要调用STextView的setData方法设置特效数据,通过getTAnimation方法获取TAnimation来操作动画。
26 | >>注:如果想用代码驱动方式写特效,请参考STextView的实现
27 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 25
5 | buildToolsVersion "25.0.3"
6 | defaultConfig {
7 | applicationId "drawn.lltvcn.com.textdemo"
8 | minSdkVersion 15
9 | targetSdkVersion 25
10 | versionCode 1
11 | versionName "1.0"
12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 |
21 | dataBinding {
22 | enabled = true
23 | }
24 |
25 | }
26 |
27 | dependencies {
28 | compile fileTree(include: ['*.jar'], dir: 'libs')
29 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
30 | exclude group: 'com.android.support', module: 'support-annotations'
31 | })
32 | compile 'com.android.support:appcompat-v7:25.3.1'
33 | testCompile 'junit:junit:4.12'
34 | compile 'com.android.support:support-v4:25.0.0'
35 | compile 'com.android.support:recyclerview-v7:25.0.0'
36 | compile 'com.google.code.gson:gson:2.8.2'
37 | compile project(':freefont')
38 | }
39 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/zhaolei/Documents/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/drawn/lltvcn/com/textdemo/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package drawn.lltvcn.com.textdemo;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumentation test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("drawn.lltvcn.com.textdemo", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
33 |
34 |
35 |
38 |
39 |
40 |
43 |
44 |
45 |
48 |
49 |
50 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/app/src/main/assets/res.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lltvcn/FreeText/d8d6daa5bb6872017e04b7f72f3e54b239a16798/app/src/main/assets/res.zip
--------------------------------------------------------------------------------
/app/src/main/assets/ttf/01方正经黑简体.TTF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lltvcn/FreeText/d8d6daa5bb6872017e04b7f72f3e54b239a16798/app/src/main/assets/ttf/01方正经黑简体.TTF
--------------------------------------------------------------------------------
/app/src/main/assets/ttf/02方正静蕾体.TTF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lltvcn/FreeText/d8d6daa5bb6872017e04b7f72f3e54b239a16798/app/src/main/assets/ttf/02方正静蕾体.TTF
--------------------------------------------------------------------------------
/app/src/main/assets/ttf/03方正兰亭纤黑简体.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lltvcn/FreeText/d8d6daa5bb6872017e04b7f72f3e54b239a16798/app/src/main/assets/ttf/03方正兰亭纤黑简体.ttf
--------------------------------------------------------------------------------
/app/src/main/assets/ttf/04汉仪铸字童年体.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lltvcn/FreeText/d8d6daa5bb6872017e04b7f72f3e54b239a16798/app/src/main/assets/ttf/04汉仪铸字童年体.ttf
--------------------------------------------------------------------------------
/app/src/main/assets/ttf/05汉仪乐喵字体.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lltvcn/FreeText/d8d6daa5bb6872017e04b7f72f3e54b239a16798/app/src/main/assets/ttf/05汉仪乐喵字体.ttf
--------------------------------------------------------------------------------
/app/src/main/assets/ttf/06汉仪良品线简5.0.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lltvcn/FreeText/d8d6daa5bb6872017e04b7f72f3e54b239a16798/app/src/main/assets/ttf/06汉仪良品线简5.0.ttf
--------------------------------------------------------------------------------
/app/src/main/assets/ttf/07兰亭特黑简.TTF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lltvcn/FreeText/d8d6daa5bb6872017e04b7f72f3e54b239a16798/app/src/main/assets/ttf/07兰亭特黑简.TTF
--------------------------------------------------------------------------------
/app/src/main/assets/ttf/08华康娃娃体W5.TTF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lltvcn/FreeText/d8d6daa5bb6872017e04b7f72f3e54b239a16798/app/src/main/assets/ttf/08华康娃娃体W5.TTF
--------------------------------------------------------------------------------
/app/src/main/assets/ttf/09造字工房朗倩.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lltvcn/FreeText/d8d6daa5bb6872017e04b7f72f3e54b239a16798/app/src/main/assets/ttf/09造字工房朗倩.ttf
--------------------------------------------------------------------------------
/app/src/main/assets/ttf/10新蒂下午茶体.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lltvcn/FreeText/d8d6daa5bb6872017e04b7f72f3e54b239a16798/app/src/main/assets/ttf/10新蒂下午茶体.ttf
--------------------------------------------------------------------------------
/app/src/main/assets/ttf/11迷你汉真广标.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lltvcn/FreeText/d8d6daa5bb6872017e04b7f72f3e54b239a16798/app/src/main/assets/ttf/11迷你汉真广标.ttf
--------------------------------------------------------------------------------
/app/src/main/assets/ttf/12方正咆哮体.TTF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lltvcn/FreeText/d8d6daa5bb6872017e04b7f72f3e54b239a16798/app/src/main/assets/ttf/12方正咆哮体.TTF
--------------------------------------------------------------------------------
/app/src/main/assets/ttf/13造字工房静黑.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lltvcn/FreeText/d8d6daa5bb6872017e04b7f72f3e54b239a16798/app/src/main/assets/ttf/13造字工房静黑.ttf
--------------------------------------------------------------------------------
/app/src/main/assets/ttf/14钱氏字体.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lltvcn/FreeText/d8d6daa5bb6872017e04b7f72f3e54b239a16798/app/src/main/assets/ttf/14钱氏字体.ttf
--------------------------------------------------------------------------------
/app/src/main/assets/ttf/15华康海报体.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lltvcn/FreeText/d8d6daa5bb6872017e04b7f72f3e54b239a16798/app/src/main/assets/ttf/15华康海报体.ttf
--------------------------------------------------------------------------------
/app/src/main/assets/ttf/16Aa小鹿.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lltvcn/FreeText/d8d6daa5bb6872017e04b7f72f3e54b239a16798/app/src/main/assets/ttf/16Aa小鹿.ttf
--------------------------------------------------------------------------------
/app/src/main/assets/ttf/17腾祥麦黑简.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lltvcn/FreeText/d8d6daa5bb6872017e04b7f72f3e54b239a16798/app/src/main/assets/ttf/17腾祥麦黑简.ttf
--------------------------------------------------------------------------------
/app/src/main/assets/ttf/18汉仪乐体.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lltvcn/FreeText/d8d6daa5bb6872017e04b7f72f3e54b239a16798/app/src/main/assets/ttf/18汉仪乐体.ttf
--------------------------------------------------------------------------------
/app/src/main/assets/ttf/19华康翩翩体.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lltvcn/FreeText/d8d6daa5bb6872017e04b7f72f3e54b239a16798/app/src/main/assets/ttf/19华康翩翩体.ttf
--------------------------------------------------------------------------------
/app/src/main/assets/ttf/20张海山锐线体2.0.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lltvcn/FreeText/d8d6daa5bb6872017e04b7f72f3e54b239a16798/app/src/main/assets/ttf/20张海山锐线体2.0.ttf
--------------------------------------------------------------------------------
/app/src/main/assets/ttf/21新蒂黑板报底字体.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lltvcn/FreeText/d8d6daa5bb6872017e04b7f72f3e54b239a16798/app/src/main/assets/ttf/21新蒂黑板报底字体.ttf
--------------------------------------------------------------------------------
/app/src/main/java/drawn/lltvcn/com/span/BaseSpan.java:
--------------------------------------------------------------------------------
1 | package drawn.lltvcn.com.span;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Paint;
5 | import android.text.Spanned;
6 | import android.text.style.RelativeSizeSpan;
7 | import android.text.style.ReplacementSpan;
8 | import android.util.Log;
9 |
10 | /**
11 | * Created by zhaolei on 2017/9/2.
12 | */
13 |
14 | public class BaseSpan extends ReplacementSpan{
15 |
16 | protected BaseSpan pre,sizeSpan;
17 | protected int horSpace,singleWidth,singleHeight;
18 | protected Paint txtPaint;
19 |
20 | public BaseSpan(){
21 |
22 | }
23 |
24 | public final BaseSpan addNext(BaseSpan span){
25 | if(span!=null){
26 | span.pre = this;
27 | return span;
28 | }else{
29 | return this;
30 | }
31 | }
32 |
33 | public BaseSpan setSizeSpan(BaseSpan span){
34 | if(span!=this){
35 | sizeSpan = span;
36 | }
37 | return this;
38 | }
39 |
40 | public void setHorSpace(int space){
41 | horSpace = space;
42 | }
43 |
44 | @Override
45 | public final int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
46 | txtPaint = paint;
47 | if(sizeSpan!=null){
48 | return sizeSpan.getSize(paint,text,start,end,fm);
49 | }
50 | if (fm != null) {
51 | Paint.FontMetricsInt fontMetricsInt = paint.getFontMetricsInt();
52 | fm.ascent = fontMetricsInt.ascent;
53 | fm.descent = fontMetricsInt.descent;
54 | fm.top = fontMetricsInt.top;
55 | fm.bottom = fontMetricsInt.bottom;
56 | handleFont(fm);
57 | }
58 | int size = (int) (paint.measureText(text,start,end)/(end-start));
59 | return measureWidth(paint,text,start,end);//需要整部分的长度,才可以正确量度其他字体位置
60 | }
61 |
62 | public void handleFont(Paint.FontMetricsInt fontMetricsInt){
63 |
64 | }
65 |
66 | private int measureWidth(Paint paint,CharSequence text, int start, int end){
67 | return (int) paint.measureText(text,start,end)+horSpace*(end-start-1);
68 | }
69 |
70 |
71 | @Override
72 | public final void draw(Canvas c, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint p) {
73 | int width = measureWidth(p,text,start,end);
74 | // if(pre!=null){
75 | // pre.beforeDrawText(c,(int)x,top, (int) (x+width),bottom,p);
76 | // }
77 | beforeDrawText(c,(int)x,top, (int) (x+width),bottom,p);
78 | // if(pre!=null){
79 | // pre.drawText(c,text,start,end,x,top,y,bottom,p);
80 | // }
81 | if(horSpace!=0){
82 | for (int i = start; i < end; i++) {
83 | // c.drawCircle(x+i*2*offsetX+offsetX,offsetY+top,4,p);
84 | drawText(c,text,i,i+1,x+measureWidth(p,text,start,i),top,y,bottom,p);
85 | }
86 | }else{
87 | drawText(c,text,start,end,x,top,y,bottom,p);
88 | }
89 | // if(pre!=null){
90 | // pre.afterDrawText(c,(int)x,top, (int) (x+width),bottom,p);
91 | // }
92 | afterDrawText(c,(int)x,top, (int) (x+width),bottom,p);
93 | }
94 |
95 | protected void beforeDrawText(Canvas c, int left, int top, int right, int bottom, Paint p){
96 | if(pre!=null){
97 | pre.beforeDrawText(c,left,top,right,bottom,p);
98 | }
99 | }
100 |
101 | protected void afterDrawText(Canvas c, int left, int top, int right, int bottom, Paint p){
102 | if(pre!=null){
103 | pre.afterDrawText(c,left,top,right,bottom,p);
104 | }
105 | }
106 |
107 | protected void drawText(Canvas c, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint p){
108 | if(pre!=null){
109 | pre.drawText(c,text,start,end,x,top,y,bottom,p);
110 | }else{
111 | c.drawText(text,start,end,x,y,p);
112 | }
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/app/src/main/java/drawn/lltvcn/com/span/ClipTxtSpan.java:
--------------------------------------------------------------------------------
1 | package drawn.lltvcn.com.span;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.Canvas;
5 | import android.graphics.Color;
6 | import android.graphics.Paint;
7 | import android.graphics.PorterDuff;
8 | import android.graphics.PorterDuffXfermode;
9 | import android.graphics.Rect;
10 | import android.graphics.RectF;
11 | import android.util.Log;
12 |
13 | import drawn.lltvcn.com.span.BaseSpan;
14 |
15 | /**
16 | * Created by zhaolei on 2017/9/1.
17 | */
18 |
19 | public class ClipTxtSpan extends BaseSpan {
20 |
21 |
22 | private Paint paint = new Paint();
23 | private static Canvas canvas;
24 | private static Bitmap bitmap;
25 | private Rect from = new Rect();
26 | private RectF to = new RectF();
27 |
28 |
29 |
30 | static {
31 | bitmap = Bitmap.createBitmap(1280,720, Bitmap.Config.ARGB_8888);
32 | canvas = new Canvas(bitmap);
33 | }
34 |
35 | private float relativeSpan;
36 | private int span;
37 |
38 | public ClipTxtSpan(float rspan){
39 | this.relativeSpan = rspan;
40 | }
41 |
42 |
43 | @Override
44 | public void handleFont(Paint.FontMetricsInt fm) {
45 | span = (int) (txtPaint.getTextSize()*relativeSpan);
46 | fm.ascent -= span/2;
47 | fm.descent += span/2;
48 | fm.top -= span/2;
49 | fm.bottom += span/2;//拉高measure的高度
50 | }
51 |
52 | @Override
53 | protected void drawText(Canvas c, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint p) {
54 | top = (int) (y+p.getFontMetrics().top);
55 | bottom = (int) (y+p.getFontMetrics().bottom);
56 | int width = (int) p.measureText(text,start,end);
57 | int height = bottom-top;
58 | paint.setColor(Color.TRANSPARENT);
59 | paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
60 | canvas.drawPaint(paint);
61 | super.drawText(canvas,text,start,end,0,0,y-top,bottom-top,p);
62 | c.save();
63 | from.set(0,0,width,height/2);
64 | to.set(x,top,x+width,top+height/2);
65 | to.offset(0,-span/2);
66 | c.drawBitmap(bitmap,from,to,null);
67 | from.offset(0,height/2);
68 | to.offset(0,height/2+span);
69 | c.drawBitmap(bitmap,from,to,null);
70 | c.restore();
71 | }
72 |
73 |
74 | }
75 |
--------------------------------------------------------------------------------
/app/src/main/java/drawn/lltvcn/com/span/LightSpan.java:
--------------------------------------------------------------------------------
1 | package drawn.lltvcn.com.span;
2 |
3 | import android.graphics.BlurMaskFilter;
4 | import android.graphics.Canvas;
5 | import android.graphics.Paint;
6 |
7 | /**
8 | * Created by zhaolei on 2017/9/14.
9 | */
10 |
11 | public class LightSpan extends BaseSpan{
12 | Paint paint = new Paint();
13 |
14 | public LightSpan(){
15 | paint.setAntiAlias(true);
16 | }
17 |
18 | @Override
19 | protected void drawText(Canvas c, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint p) {
20 | paint.set(p);
21 | paint.setMaskFilter(new BlurMaskFilter(10, BlurMaskFilter.Blur.SOLID));
22 | super.drawText(c, text, start, end, x, top, y, bottom, paint);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/main/java/drawn/lltvcn/com/span/LineColorSpan.java:
--------------------------------------------------------------------------------
1 | package drawn.lltvcn.com.span;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Paint;
5 |
6 | /**
7 | * Created by zhaolei on 2017/9/4.
8 | */
9 |
10 | public class LineColorSpan extends BaseSpan {
11 |
12 | private boolean isForeground;
13 | private Paint paint;
14 |
15 | public LineColorSpan(int color,boolean isForeground){
16 | paint = new Paint();
17 | paint.setColor(color);
18 | paint.setAntiAlias(true);
19 | paint.setStyle(Paint.Style.FILL);
20 | this.isForeground = isForeground;
21 | }
22 |
23 |
24 | @Override
25 | protected void afterDrawText(Canvas c, int left, int top, int right, int bottom, Paint p) {
26 | if(isForeground){
27 | c.drawRect(left,top,right,bottom,paint);
28 | }
29 | }
30 |
31 | @Override
32 | protected void beforeDrawText(Canvas c, int left, int top, int right, int bottom, Paint p) {
33 | if(!isForeground){
34 | c.drawRect(left-5,top,right+5,bottom,paint);
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/java/drawn/lltvcn/com/span/LineImgSpan.java:
--------------------------------------------------------------------------------
1 | package drawn.lltvcn.com.span;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.Canvas;
5 | import android.graphics.Color;
6 | import android.graphics.Paint;
7 | import android.graphics.Rect;
8 | import android.graphics.drawable.BitmapDrawable;
9 | import android.util.Log;
10 | import android.view.Gravity;
11 |
12 | /**
13 | * Created by zhaolei on 2017/9/4.
14 | */
15 |
16 | public class LineImgSpan extends BaseSpan {
17 |
18 | protected Bitmap bitmap;
19 | private Paint paint;
20 | private int gravity;
21 | private float span;
22 | private boolean isForeground,isFit;
23 | private Rect from,to;
24 |
25 |
26 | public LineImgSpan(Bitmap bm, int gravity){
27 | this(bm,gravity,0,false);
28 | }
29 |
30 | public LineImgSpan(Bitmap bm, int gravity, float span){
31 | this(bm,gravity,span,false);
32 | }
33 |
34 |
35 | public LineImgSpan(Bitmap bm, int gravity, float span, boolean isForeground){
36 | this(bm,gravity,span,isForeground,false);
37 | }
38 |
39 | public LineImgSpan(Bitmap bm, int gravity, float span, boolean isForeground,boolean isFit){
40 | bitmap = bm;
41 | paint = new Paint();
42 | paint.setStyle(Paint.Style.FILL);
43 | paint.setColor(Color.BLUE);
44 | this.span = span;
45 | this.gravity = gravity;
46 | this.isForeground = isForeground;
47 | this.isFit = isFit;
48 | from = new Rect();
49 | to = new Rect();
50 | from.set(0,0,bitmap.getWidth(),bitmap.getHeight());
51 | }
52 |
53 | @Override
54 | public void handleFont(Paint.FontMetricsInt fm) {
55 |
56 | if(span>0){
57 | int spanInt = (int) (txtPaint.getTextSize()*span);
58 | switch (getGravity()){
59 | case Gravity.TOP:
60 | fm.descent += spanInt;
61 | fm.bottom += spanInt;//拉高measure的高度
62 | break;
63 | case Gravity.CENTER:
64 | fm.ascent -= spanInt/2;
65 | fm.descent += spanInt/2;
66 | fm.top -= spanInt/2;
67 | fm.bottom += spanInt/2;//拉高measure的高度
68 | break;
69 | case Gravity.BOTTOM:
70 | fm.ascent -= spanInt/2;
71 | fm.descent += spanInt/2;
72 | fm.top -= spanInt/2;
73 | fm.bottom += spanInt/2;//拉高measure的高度
74 | // fm.ascent -= spanInt;
75 | // fm.top -= spanInt;
76 | break;
77 | }
78 | }
79 | if(isFit){
80 |
81 | }
82 | }
83 |
84 | private int getGravity(){
85 | if((gravity&Gravity.TOP)==Gravity.TOP){
86 | return Gravity.TOP;
87 | }
88 | if((gravity&Gravity.CENTER)==Gravity.CENTER){
89 | return Gravity.CENTER;
90 | }
91 | if((gravity&Gravity.BOTTOM)==Gravity.BOTTOM){
92 | return Gravity.BOTTOM;
93 | }
94 | return gravity;
95 | }
96 |
97 |
98 | @Override
99 | protected void beforeDrawText(Canvas c, int left, int top, int right, int bottom, Paint p) {
100 | if(!isForeground){
101 | drawImg(c,left,top,right,bottom,p);
102 | }
103 | }
104 |
105 | @Override
106 | protected void afterDrawText(Canvas c, int left, int top, int right, int bottom, Paint p) {
107 | if(isForeground){
108 | drawImg(c,left,top,right,bottom,p);
109 | }
110 | }
111 |
112 |
113 | private void drawImg(Canvas c, int left, int top, int right, int bottom, Paint p){
114 | Log.i("kkkkk","drawImg"+left+":::"+top);
115 | paint.setStyle(Paint.Style.FILL);
116 | c.save();
117 | float scale = 1;
118 | if(isFit){
119 | scale = ((float)(bottom-top)/bitmap.getHeight());
120 | }
121 | to.set(0,0, (int) (bitmap.getWidth()*scale), (int) (bitmap.getHeight()*scale));
122 | to.offset(left,top);
123 | int moreH = bottom-top-to.height();
124 | if(moreH!=0){
125 | switch (getGravity()){
126 | case Gravity.CENTER:
127 | to.offset(0,moreH/2);
128 | break;
129 | case Gravity.BOTTOM:
130 | to.offset(0,moreH);
131 | break;
132 | }
133 | }
134 |
135 | drawBitmap(c,from,to,right-left);
136 | c.restore();
137 | }
138 |
139 | protected void drawBitmap(Canvas c,Rect from,Rect to,int width){
140 | int count = width/to.width();
141 | if(count==0){
142 | count = 1;
143 | }
144 | to.offset((width-(to.width()*count))/2,0);
145 | for (int i = 0; i < count; i++) {
146 | c.drawBitmap(bitmap,from,to,null);
147 | to.offset(to.width(),0);
148 | }
149 | }
150 |
151 |
152 | }
153 |
--------------------------------------------------------------------------------
/app/src/main/java/drawn/lltvcn/com/span/OffsetTxtSpan.java:
--------------------------------------------------------------------------------
1 | package drawn.lltvcn.com.span;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.Canvas;
5 | import android.graphics.Color;
6 | import android.graphics.Paint;
7 | import android.graphics.PorterDuff;
8 | import android.graphics.PorterDuffXfermode;
9 | import android.graphics.Rect;
10 | import android.graphics.RectF;
11 |
12 | /**
13 | * Created by zhaolei on 2017/9/5.
14 | */
15 |
16 | public class OffsetTxtSpan extends BaseSpan {
17 | private Paint paint = new Paint();
18 | private static Canvas canvas;
19 | private static Bitmap bitmap;
20 | private Rect from = new Rect();
21 | private RectF to = new RectF();
22 |
23 |
24 | static {
25 | bitmap = Bitmap.createBitmap(720,1280, Bitmap.Config.ARGB_8888);
26 | canvas = new Canvas(bitmap);
27 | }
28 |
29 |
30 | private float[] positions,offsets;
31 |
32 |
33 | public OffsetTxtSpan(float[] positions, float[] offsets){
34 | this.positions = positions;
35 | this.offsets = offsets;
36 | if(positions==null&&offsets==null){
37 |
38 | }else{
39 | if(positions.length!=offsets.length){
40 | throw new RuntimeException("param length wrong!");
41 | }
42 | }
43 |
44 | }
45 |
46 |
47 | @Override
48 | protected void drawText(Canvas c, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint p) {
49 | int width = (int) p.measureText(text,start,end);
50 | int height = bottom-top;
51 | paint.setColor(Color.TRANSPARENT);
52 | paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
53 | canvas.drawPaint(paint);
54 | super.drawText(canvas,text,start,end,0,0,y-top,bottom-top,p);
55 | // canvas.drawText(text,start,end,0,y-top,p);//减去top是为了画在bitmap的最上端
56 | if(positions!=null){
57 | c.save();
58 | c.translate(x,top);
59 | int offsetY = 0;
60 | for (int i = 0; i < positions.length; i++) {
61 | from.set(0,offsetY,width,offsetY+=height*positions[i]);
62 | to.set(0,from.top,width,from.bottom);
63 | to.offset(offsets[i]*p.getTextSize(),0);
64 | c.drawBitmap(bitmap,from,to,null);
65 | }
66 | c.restore();
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/app/src/main/java/drawn/lltvcn/com/span/RandomBgSpan.java:
--------------------------------------------------------------------------------
1 | package drawn.lltvcn.com.span;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.Canvas;
5 | import android.graphics.Rect;
6 |
7 | import java.util.Random;
8 |
9 | /**
10 | * Created by zhaolei on 2017/9/4.
11 | */
12 |
13 | public class RandomBgSpan extends LineImgSpan {
14 |
15 |
16 | public RandomBgSpan(Bitmap bm, int gravity, int span, boolean isForeground, boolean isFit) {
17 | super(bm, gravity, span, isForeground, isFit);
18 | }
19 |
20 | public RandomBgSpan(Bitmap bm, int gravity, int span, boolean isForeground) {
21 | this(bm, gravity, span, isForeground, true);
22 | }
23 |
24 |
25 | @Override
26 | protected void drawBitmap(Canvas c, Rect from, Rect to, int width) {
27 | // int count = width/to.width();
28 | // to.offset((width-(to.width()*count))/2,0);
29 | // for (int i = 0; i < count; i++) {
30 | // c.drawBitmap(img,from,to,null);
31 | // to.offset(to.width(),0);
32 | // }
33 | int end = to.width();
34 | int offset = 0;
35 | Random random = new Random(500);
36 |
37 | while (end<=width){
38 | c.drawBitmap(bitmap,from,to,null);
39 | offset = random.nextInt(to.width()/2)+to.width()/2;
40 | if(end+offset>width){
41 | offset = width-end;
42 | if(offset==0){
43 | break;
44 | }
45 | }
46 | to.offset(offset,0);
47 | end += offset;
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/app/src/main/java/drawn/lltvcn/com/span/ShaderShadowSpan.java:
--------------------------------------------------------------------------------
1 | package drawn.lltvcn.com.span;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.BitmapShader;
5 | import android.graphics.Canvas;
6 | import android.graphics.Paint;
7 | import android.graphics.Shader;
8 |
9 | /**
10 | * Created by zhaolei on 2017/9/4.
11 | */
12 |
13 | public class ShaderShadowSpan extends BaseSpan {
14 |
15 | private BitmapShader shader;
16 |
17 |
18 | public ShaderShadowSpan(Bitmap bitmap){
19 | shader = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
20 | }
21 |
22 |
23 | @Override
24 | protected void drawText(Canvas c, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint p) {
25 | drawShadowText(c, text, start, end, x, top, y, bottom, p);
26 | }
27 |
28 | private void drawShadowText(Canvas c, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint p){
29 | Shader tshader = p.getShader();
30 | p.setShader(shader);
31 | super.drawText(c, text, start, end, x+5, top, y+5, bottom, p);
32 | p.setShader(tshader);
33 | super.drawText(c, text, start, end, x, top, y, bottom, p);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/java/drawn/lltvcn/com/span/ShakeTxtSpan.java:
--------------------------------------------------------------------------------
1 | package drawn.lltvcn.com.span;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Color;
5 | import android.graphics.Paint;
6 |
7 | /**
8 | * Created by zhaolei on 2017/9/5.
9 | */
10 |
11 | public class ShakeTxtSpan extends BaseSpan {
12 |
13 |
14 | @Override
15 | protected void drawText(Canvas c, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint p) {
16 | int color = p.getColor();
17 | int alpha = p.getAlpha();
18 | p.setAlpha(100);
19 | p.setColor(Color.rgb(80,236,204));
20 | super.drawText(c, text, start, end, x-3, top, y-3, bottom, p);
21 | p.setColor(Color.rgb(222,7,84));
22 | super.drawText(c, text, start, end, x+3, top, y+3, bottom, p);
23 | p.setAlpha(alpha);
24 | p.setColor(color);
25 | super.drawText(c, text, start, end, x, top, y, bottom, p);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/main/java/drawn/lltvcn/com/span/SingleTxtBgSpan.java:
--------------------------------------------------------------------------------
1 | package drawn.lltvcn.com.span;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.Canvas;
5 | import android.graphics.Paint;
6 | import android.graphics.Rect;
7 | import android.view.Gravity;
8 |
9 | /**
10 | * Created by zhaolei on 2017/9/11.
11 | */
12 |
13 | public class SingleTxtBgSpan extends BaseSpan{
14 |
15 | public static final int MODE_NO = 0;
16 | public static final int MODE_FITX = 1;
17 | public static final int MODE_FITY = 2;
18 | public static final int MODE_FIT_CENTER = 3;
19 | private Bitmap bm;
20 | private int fit;
21 | private Rect from,to;
22 |
23 | public SingleTxtBgSpan(Bitmap bg,int fitMode){
24 | bm = bg;
25 | fit = fitMode;
26 | from = new Rect();
27 | to = new Rect();
28 | from.set(0,0,bg.getWidth(),bg.getHeight());
29 | to.set(0,0,bg.getWidth(),bg.getHeight());
30 | }
31 |
32 |
33 | @Override
34 | protected void drawText(Canvas c, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint p) {
35 | float scale = 1;
36 | to.set(from.left,from.top,from.right,from.bottom);
37 | switch (fit){
38 | case MODE_NO:
39 | // scale = ((float)(bottom-top)/bm.getHeight());
40 | break;
41 | }
42 | to.offset((int) x,top);
43 | int moreH = bottom-top-to.height();
44 | int moreW = (int) (p.getTextSize()-to.width());
45 | to.offset(moreW/2,moreH/2);
46 | for (int i = start; i < end; i++) {
47 | // c.drawCircle(x+i*2*offsetX+offsetX,offsetY+top,4,p);
48 | c.drawBitmap(bm,from,to,null);
49 | to.offset((int) p.getTextSize(),0);
50 | }
51 | super.drawText(c,text,start,end,x,top,y,bottom,p);
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/app/src/main/java/drawn/lltvcn/com/span/SingleTxtRotateSpan.java:
--------------------------------------------------------------------------------
1 | package drawn.lltvcn.com.span;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Paint;
5 | import android.view.Surface;
6 |
7 | /**
8 | * Created by zhaolei on 2017/9/11.
9 | */
10 |
11 | public class SingleTxtRotateSpan extends BaseSpan{
12 | private float degree;
13 |
14 | public SingleTxtRotateSpan(float degree){
15 | this.degree = degree;
16 | }
17 |
18 |
19 | @Override
20 | protected void drawText(Canvas c, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint p) {
21 | float offsetX = p.getTextSize()/2;
22 | float offsetY = (bottom-top)/2;
23 | for (int i = 0; i < end-start; i++) {
24 | c.drawCircle(x+i*2*offsetX+offsetX,offsetY+top,4,p);
25 | c.save();
26 | c.rotate(-degree,x+i*(2*offsetX)+offsetX,offsetY+top);
27 | super.drawText(c, text, i+start, i+1+start, x+i*(2*offsetX), top, y, bottom, p);
28 | c.restore();
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/java/drawn/lltvcn/com/span/StokeTxtSpan.java:
--------------------------------------------------------------------------------
1 | package drawn.lltvcn.com.span;
2 |
3 | import android.graphics.BlurMaskFilter;
4 | import android.graphics.Canvas;
5 | import android.graphics.Color;
6 | import android.graphics.CornerPathEffect;
7 | import android.graphics.Paint;
8 | import android.graphics.PathEffect;
9 |
10 | /**
11 | * Created by zhaolei on 2017/9/4.
12 | */
13 |
14 | public class StokeTxtSpan extends BaseSpan {
15 |
16 | private Paint paint = new Paint();
17 | private float relativeWidth;
18 | private int color;
19 |
20 | public StokeTxtSpan(float rWidth,int color){
21 | this.color = color;
22 | relativeWidth = rWidth;
23 | }
24 |
25 |
26 | @Override
27 | protected void drawText(Canvas c, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint p) {
28 | paint.set(p);
29 | paint.setStyle(Paint.Style.FILL_AND_STROKE);
30 | paint.setStrokeJoin(Paint.Join.ROUND);
31 | paint.setStrokeWidth(p.getTextSize()*relativeWidth);
32 | paint.setColor(color);
33 | // paint.setMaskFilter(new BlurMaskFilter(p.getTextSize()*relativeWidth/2F, BlurMaskFilter.Blur.SOLID));
34 | paint.setShadowLayer(p.getTextSize()*relativeWidth*2,0.5f,0.5f, Color.argb(100,Color.red(color),Color.green(color),Color.blue(color)));
35 | super.drawText(c, text, start, end, x, top, y, bottom, paint);
36 | super.drawText(c, text, start, end, x, top, y, bottom, p);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/app/src/main/java/drawn/lltvcn/com/span/TxtSpan.java:
--------------------------------------------------------------------------------
1 | package drawn.lltvcn.com.span;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Color;
5 | import android.graphics.Paint;
6 |
7 | /**
8 | * Created by zhaolei on 2017/9/21.
9 | */
10 |
11 | public class TxtSpan extends BaseSpan{
12 |
13 | private static Paint savePaint = new Paint();
14 | private PaintHandler handler;
15 |
16 | public TxtSpan setPaintHandler(PaintHandler handler){
17 | this.handler = handler;
18 | return this;
19 | }
20 |
21 | @Override
22 | protected void drawText(Canvas c, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint p) {
23 | savePaint.set(p);
24 | handler.handlePaint(savePaint);
25 | super.drawText(c, text, start, end, x, top, y, bottom, savePaint);
26 | }
27 |
28 | public interface PaintHandler{
29 | void handlePaint(Paint p);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/java/drawn/lltvcn/com/textdemo/DemoActivity.java:
--------------------------------------------------------------------------------
1 | package drawn.lltvcn.com.textdemo;
2 |
3 | import android.app.Activity;
4 | import android.graphics.Color;
5 | import android.graphics.drawable.ColorDrawable;
6 | import android.os.Bundle;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.BaseAdapter;
11 | import android.widget.ListView;
12 | import android.widget.TextView;
13 |
14 | import com.lltvcn.freefont.core.animation.A;
15 | import com.lltvcn.freefont.core.data.AniData;
16 | import com.lltvcn.freefont.core.data.DrawData;
17 | import com.lltvcn.freefont.core.view.STextView;
18 |
19 | import java.util.ArrayList;
20 |
21 | import drawn.lltvcn.com.util.FileUtil;
22 | import drawn.lltvcn.com.util.FontUtil;
23 | import drawn.lltvcn.com.util.SUtil;
24 |
25 | /**
26 | * Created by zhaolei on 2018/1/5.
27 | */
28 |
29 | public class DemoActivity extends Activity{
30 |
31 | private ListView listView;
32 |
33 |
34 | @Override
35 | protected void onCreate(Bundle savedInstanceState) {
36 | super.onCreate(savedInstanceState);
37 | setContentView(R.layout.activity_demo);
38 | getWindow().setBackgroundDrawable(new ColorDrawable(Color.WHITE));
39 |
40 | datas = new ArrayList<>();
41 | Data d1 = new Data();
42 | d1.title = "组合动画";
43 | d1.data = FileUtil.getDrawData("文字颜色顺序变化");
44 | d1.font = "15华康海报体.ttf";
45 | d1.data.aniType = A.BOTTOM_IN_SCALE_UP_OUT;
46 | datas.add(d1);
47 |
48 | d1 = new Data();
49 | d1.title = "淡入淡出动画";
50 | d1.data = FileUtil.getDrawData("文字颜色顺序变化");
51 | d1.font = "15华康海报体.ttf";
52 | d1.data.aniType = A.SINGLE_RIGHT_FADE_INF_LEFT_FADE_OUT;
53 | datas.add(d1);
54 |
55 | d1 = new Data();
56 | d1.title = "单字旋转动画";
57 | d1.data = FileUtil.getDrawData("文字颜色顺序变化");
58 | d1.data.aniType = A.SINGLE_ROTATE;
59 | d1.font = "15华康海报体.ttf";
60 | datas.add(d1);
61 |
62 | d1 = new Data();
63 | d1.title = "整体旋转动画";
64 | d1.data = FileUtil.getDrawData("文字颜色顺序变化");
65 | d1.data.aniType = A.ROTATE_REPEAT;
66 | d1.font = "15华康海报体.ttf";
67 | datas.add(d1);
68 |
69 | d1 = new Data();
70 | d1.title = "上下移动动画";
71 | d1.data = FileUtil.getDrawData("文字颜色顺序变化");
72 | d1.data.aniType = A.SINGLE_UP_DOWN;
73 | d1.font = "15华康海报体.ttf";
74 | datas.add(d1);
75 |
76 |
77 | d1 = new Data();
78 | d1.title = "下划线+发光";
79 | d1.data = FileUtil.getDrawData("下划线+发光");
80 | d1.font = "15华康海报体.ttf";
81 | datas.add(d1);
82 |
83 | d1 = new Data();
84 | d1.title = "中划线";
85 | d1.data = FileUtil.getDrawData("中划线");
86 | d1.font = "15华康海报体.ttf";
87 | datas.add(d1);
88 |
89 | d1 = new Data();
90 | d1.title = "抖音效果2";
91 | d1.data = FileUtil.getDrawData("抖音2");
92 | d1.font = "15华康海报体.ttf";
93 | datas.add(d1);
94 |
95 | d1 = new Data();
96 | d1.title = "缩放效果";
97 | d1.data = FileUtil.getDrawData("缩放效果");
98 | d1.font = "15华康海报体.ttf";
99 | datas.add(d1);
100 |
101 |
102 | d1 = new Data();
103 | d1.title = "每个文字叠加图片";
104 | d1.data = FileUtil.getDrawData("单个字叠加图片");
105 | d1.font = "15华康海报体.ttf";
106 | datas.add(d1);
107 |
108 | d1 = new Data();
109 | d1.title = "每个文字渐变";
110 | d1.data = FileUtil.getDrawData("单个文字渐变");
111 | d1.font = "15华康海报体.ttf";
112 | datas.add(d1);
113 |
114 | d1 = new Data();
115 | d1.title = "每个文字加背景图";
116 | d1.data = FileUtil.getDrawData("背景图");
117 | d1.font = "15华康海报体.ttf";
118 | datas.add(d1);
119 |
120 | d1 = new Data();
121 | d1.title = "切割文字";
122 | d1.data = FileUtil.getDrawData("切割文字");
123 | d1.font = "15华康海报体.ttf";
124 | datas.add(d1);
125 |
126 | listView = (ListView) findViewById(R.id.list_view);
127 | listView.setAdapter(new MyAdapter());
128 |
129 | }
130 |
131 |
132 |
133 |
134 | private class Data{
135 | String title;
136 | String font;
137 | DrawData data;
138 | }
139 |
140 | private ArrayList datas;
141 |
142 | private class MyAdapter extends BaseAdapter{
143 |
144 | @Override
145 | public int getCount() {
146 | return datas==null?0:datas.size();
147 | }
148 |
149 | @Override
150 | public Data getItem(int position) {
151 | return datas.get(position);
152 | }
153 |
154 | @Override
155 | public long getItemId(int position) {
156 | return position;
157 | }
158 |
159 | @Override
160 | public View getView(int position, View convertView, ViewGroup parent) {
161 | ViewHolder holder = null;
162 | if(convertView == null){
163 | convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_demo,parent,false);
164 | holder = new ViewHolder();
165 | holder.tvTitle = (TextView) convertView.findViewById(R.id.tv_title);
166 | holder.tvContent = (STextView) convertView.findViewById(R.id.tv_content);
167 | holder.tvContent.setLocalSourcePath(FileUtil.getImgDir());
168 | convertView.setTag(holder);
169 | }else{
170 | holder = (ViewHolder) convertView.getTag();
171 | }
172 | Data data = getItem(position);
173 | holder.tvTitle.setText(data.title);
174 | holder.tvTitle.setVisibility(View.GONE);
175 | holder.tvContent.setText(data.title);
176 | holder.tvContent.setTypeface(FontUtil.getTypeface(data.font));
177 | if(holder.tvContent.getTAnimation()!=null){
178 | holder.tvContent.getTAnimation().stop();
179 | }
180 | holder.tvContent.setData(data.data);
181 | if(holder.tvContent.getTAnimation()!=null){
182 | holder.tvContent.getTAnimation().start();
183 | }
184 | return convertView;
185 | }
186 | }
187 |
188 | private class ViewHolder{
189 | TextView tvTitle;
190 | STextView tvContent;
191 | }
192 | }
193 |
--------------------------------------------------------------------------------
/app/src/main/java/drawn/lltvcn/com/textdemo/ListActivity.java:
--------------------------------------------------------------------------------
1 | package drawn.lltvcn.com.textdemo;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.view.View;
7 | import android.widget.EditText;
8 |
9 | /**
10 | * Created by zhaolei on 2017/10/20.
11 | */
12 |
13 | public class ListActivity extends Activity{
14 |
15 | @Override
16 | protected void onCreate(Bundle savedInstanceState) {
17 | super.onCreate(savedInstanceState);
18 | setContentView(R.layout.layout_list);
19 | }
20 |
21 |
22 | public void toEdit(View view){
23 | startActivity(new Intent(this,EditActivity.class));
24 | }
25 |
26 | public void toReview(View view){
27 | startActivity(new Intent(this,ReviewActivity.class));
28 | }
29 |
30 | public void toDemo(View view) {startActivity(new Intent(this,DemoActivity.class));}
31 |
32 | public void toReviewAni(View view){
33 | startActivity(new Intent(this,ReviewAniActivity.class));
34 |
35 | }
36 |
37 | public void toCode(View view){
38 | startActivity(new Intent(this,CodeActivity.class));
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/app/src/main/java/drawn/lltvcn/com/textdemo/MainApplication.java:
--------------------------------------------------------------------------------
1 | package drawn.lltvcn.com.textdemo;
2 |
3 | import android.app.Application;
4 |
5 | import java.io.File;
6 | import java.io.IOException;
7 |
8 | import drawn.lltvcn.com.util.FileUtil;
9 | import drawn.lltvcn.com.util.ZipUtil;
10 |
11 | /**
12 | * Created by zhaolei on 2017/10/19.
13 | */
14 |
15 | public class MainApplication extends Application{
16 |
17 | private static MainApplication instance;
18 | public static MainApplication getInstance(){
19 | return instance;
20 | }
21 |
22 | @Override
23 | public void onCreate() {
24 | super.onCreate();
25 | instance = this;
26 | if(!new File(FileUtil.getRootPath()+"e.e").exists()){
27 | try {
28 | ZipUtil.decompress(getAssets().open("res.zip"),FileUtil.getRootPath(),false);
29 | new File(FileUtil.getRootPath()+"e.e").createNewFile();
30 | } catch (IOException e) {
31 | e.printStackTrace();
32 | }
33 |
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/java/drawn/lltvcn/com/textdemo/ParamProvider.java:
--------------------------------------------------------------------------------
1 | package drawn.lltvcn.com.textdemo;
2 |
3 | /**
4 | * Created by zhaolei on 2017/8/17.
5 | */
6 |
7 | public interface ParamProvider {
8 |
9 | int getInt(int index,int def);
10 |
11 | float getFloat(int index,float def);
12 |
13 | int getIntCount();
14 |
15 | int getFloatCount();
16 |
17 | void setInt(int index,int param);
18 |
19 | void setFloat(int index,float param);
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/java/drawn/lltvcn/com/textdemo/ParamProviderImpl.java:
--------------------------------------------------------------------------------
1 | package drawn.lltvcn.com.textdemo;
2 |
3 | import android.util.SparseArray;
4 |
5 | import java.util.ArrayList;
6 |
7 | /**
8 | * Created by zhaolei on 2017/8/17.
9 | */
10 |
11 | public class ParamProviderImpl implements ParamProvider{
12 |
13 | private SparseArray integers = new SparseArray<>(1);
14 | private SparseArray floats = new SparseArray<>(1);
15 |
16 | @Override
17 | public int getInt(int index, int def) {
18 | if(integers.get(index)==null){
19 | integers.put(index,def);
20 | }
21 | return integers.get(index);
22 | }
23 |
24 | @Override
25 | public float getFloat(int index, float def) {
26 | if(floats.get(index)==null){
27 | floats.put(index,def);
28 | }
29 | return floats.get(index);
30 | }
31 |
32 | @Override
33 | public int getIntCount() {
34 | return integers.size();
35 | }
36 |
37 | @Override
38 | public int getFloatCount() {
39 | return floats.size();
40 | }
41 |
42 | @Override
43 | public void setInt(int index, int param) {
44 | integers.put(index,param);
45 | }
46 |
47 | @Override
48 | public void setFloat(int index, float param) {
49 | floats.put(index,param);
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/app/src/main/java/drawn/lltvcn/com/textdemo/ReviewActivity.java:
--------------------------------------------------------------------------------
1 | package drawn.lltvcn.com.textdemo;
2 |
3 | import android.app.Activity;
4 | import android.graphics.Color;
5 | import android.graphics.Paint;
6 | import android.os.Bundle;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.widget.EditText;
10 |
11 | import com.google.gson.Gson;
12 | import com.lltvcn.freefont.core.animation.A;
13 | import com.lltvcn.freefont.core.data.DrawData;
14 | import com.lltvcn.freefont.core.view.STextView;
15 |
16 | import java.io.File;
17 | import java.io.FileNotFoundException;
18 | import java.io.FileReader;
19 | import java.io.IOException;
20 | import java.util.ArrayList;
21 |
22 | import drawn.lltvcn.com.textdemo.controller.EditParamViewController;
23 | import drawn.lltvcn.com.textdemo.controller.SelectController;
24 | import drawn.lltvcn.com.util.FileUtil;
25 | import drawn.lltvcn.com.util.FontUtil;
26 | import drawn.lltvcn.com.util.SUtil;
27 |
28 | /**
29 | * Created by zhaolei on 2017/11/21.
30 | */
31 |
32 | public class ReviewActivity extends Activity{
33 | STextView tv;
34 | SelectController selectController;
35 | String[] fileNames;
36 | String[] fontNames;
37 |
38 | @Override
39 | protected void onCreate(Bundle savedInstanceState) {
40 | super.onCreate(savedInstanceState);
41 | setContentView(R.layout.layout_review);
42 | fontNames = FontUtil.getFontNames();
43 | tv = (STextView) findViewById(R.id.tv);
44 | tv.setText(SUtil.getTxt());
45 | tv.setLocalSourcePath(FileUtil.getImgDir());
46 | selectController = new SelectController();
47 | selectController.init((ViewGroup) findViewById(R.id.fl_cotainer), new EditParamViewController.VisiableListener() {
48 | @Override
49 | public void onVisable(boolean visiable) {
50 | }
51 | });
52 | File file = new File(FileUtil.getDataDir());
53 | fileNames = file.list();
54 | findViewById(R.id.btn_add).setOnClickListener(new View.OnClickListener() {
55 | @Override
56 | public void onClick(View v) {
57 | selectController.show(fileNames, false, new SelectController.ResultListener() {
58 | @Override
59 | public void onConfrim(ArrayList result) {
60 | String name = result.get(0);
61 | String dir = FileUtil.getDataDirByName(name);
62 | try {
63 | FileReader reader = new FileReader(dir+File.separator+name+".txt");
64 | DrawData data = new Gson().fromJson(reader,DrawData.class);
65 | reader.close();
66 | tv.setData(data);
67 | if(tv.getTAnimation()!=null){
68 | tv.getTAnimation().start();
69 | }
70 | } catch (FileNotFoundException e) {
71 | e.printStackTrace();
72 | } catch (IOException e) {
73 | e.printStackTrace();
74 | }
75 | }
76 | });
77 | }
78 | });
79 | findViewById(R.id.btn_font).setOnClickListener(new View.OnClickListener() {
80 | @Override
81 | public void onClick(View v) {
82 | selectController.show(fontNames, false, new SelectController.ResultListener() {
83 | @Override
84 | public void onConfrim(ArrayList result) {
85 | if(result!=null&&result.size()>0){
86 | tv.setTypeface(FontUtil.getTypeface(result.get(0)));
87 | }else{
88 | tv.setTypeface(null);
89 | }
90 | }
91 | });
92 | }
93 | });
94 |
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/app/src/main/java/drawn/lltvcn/com/textdemo/ReviewAniActivity.java:
--------------------------------------------------------------------------------
1 | package drawn.lltvcn.com.textdemo;
2 |
3 | import android.app.Activity;
4 | import android.graphics.Color;
5 | import android.graphics.Paint;
6 | import android.os.Bundle;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.widget.EditText;
10 |
11 | import com.google.gson.Gson;
12 | import com.lltvcn.freefont.core.animation.A;
13 | import com.lltvcn.freefont.core.data.DrawData;
14 | import com.lltvcn.freefont.core.view.STextView;
15 |
16 | import java.io.File;
17 | import java.io.FileNotFoundException;
18 | import java.io.FileReader;
19 | import java.io.IOException;
20 | import java.util.ArrayList;
21 |
22 | import drawn.lltvcn.com.textdemo.controller.EditParamViewController;
23 | import drawn.lltvcn.com.textdemo.controller.SelectController;
24 | import drawn.lltvcn.com.util.FileUtil;
25 | import drawn.lltvcn.com.util.FontUtil;
26 | import drawn.lltvcn.com.util.SUtil;
27 |
28 | /**
29 | * Created by zhaolei on 2017/11/21.
30 | */
31 |
32 | public class ReviewAniActivity extends Activity{
33 | STextView tv;
34 | SelectController selectController;
35 | String[] fileNames,aniNames,fontNames;
36 | DrawData drawData;
37 | int[] aniTypes;
38 |
39 | {
40 | aniNames = new String[]{"出现1","出现2(单字旋转)","出现4(大->小)","出现7(淡入淡出)","基础2(单字上下抖动)","基础3(所有字旋转)","基础4(单字缩放)","基础1(X)"};
41 | aniTypes = new int[]{A.BOTTOM_IN_SCALE_UP_OUT,A.SINGLE_ROTATE,A.SCALE_SHOW,A.SINGLE_RIGHT_FADE_INF_LEFT_FADE_OUT,A.SINGLE_UP_DOWN,A.ROTATE_REPEAT,A.SINGLE_SCALE,A.SINGLE_X};
42 | }
43 |
44 | @Override
45 | protected void onCreate(Bundle savedInstanceState) {
46 | super.onCreate(savedInstanceState);
47 | setContentView(R.layout.layout_review_ani);
48 | tv = (STextView) findViewById(R.id.tv);
49 | fontNames = FontUtil.getFontNames();
50 | tv.setLocalSourcePath(FileUtil.getImgDir());
51 | tv.setText(SUtil.getTxt());
52 | selectController = new SelectController();
53 | selectController.init((ViewGroup) findViewById(R.id.fl_cotainer), new EditParamViewController.VisiableListener() {
54 | @Override
55 | public void onVisable(boolean visiable) {
56 | }
57 | });
58 | File file = new File(FileUtil.getDataDir());
59 | fileNames = file.list();
60 | findViewById(R.id.btn_add).setOnClickListener(new View.OnClickListener() {
61 | @Override
62 | public void onClick(View v) {
63 | selectController.show(fileNames, false, new SelectController.ResultListener() {
64 | @Override
65 | public void onConfrim(ArrayList result) {
66 | String name = result.get(0);
67 | String dir = FileUtil.getDataDirByName(name);
68 | try {
69 | FileReader reader = new FileReader(dir+File.separator+name+".txt");
70 | DrawData data = new Gson().fromJson(reader,DrawData.class);
71 | drawData = data;
72 | reader.close();
73 | tv.setData(data);
74 | if(tv.getTAnimation()!=null){
75 | tv.getTAnimation().start();
76 | }
77 | } catch (FileNotFoundException e) {
78 | e.printStackTrace();
79 | } catch (IOException e) {
80 | e.printStackTrace();
81 | }
82 | }
83 | });
84 | }
85 | });
86 | findViewById(R.id.btn_ani).setOnClickListener(new View.OnClickListener() {
87 | @Override
88 | public void onClick(View v) {
89 | selectController.show(aniNames, false, new SelectController.ResultListener() {
90 | @Override
91 | public void onConfrim(ArrayList result) {
92 | for (int i = 0; i < aniNames.length; i++) {
93 | if(aniNames[i].equals(result.get(0))){
94 | if(drawData!=null){
95 | drawData.aniType = aniTypes[i];
96 | if(tv.getTAnimation()!=null){
97 | tv.getTAnimation().stop();
98 | }
99 | tv.setData(drawData);
100 | if(tv.getTAnimation()!=null){
101 | tv.getTAnimation().start();
102 | }
103 | }
104 | }
105 | }
106 | }
107 | });
108 | }
109 | });
110 |
111 | findViewById(R.id.btn_font).setOnClickListener(new View.OnClickListener() {
112 | @Override
113 | public void onClick(View v) {
114 | selectController.show(fontNames, false, new SelectController.ResultListener() {
115 | @Override
116 | public void onConfrim(ArrayList result) {
117 | if(result!=null&&result.size()>0){
118 | tv.setTypeface(FontUtil.getTypeface(result.get(0)));
119 | }else{
120 | tv.setTypeface(null);
121 | }
122 | }
123 | });
124 | }
125 | });
126 |
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/app/src/main/java/drawn/lltvcn/com/textdemo/TxtShader2.java:
--------------------------------------------------------------------------------
1 | package drawn.lltvcn.com.textdemo;
2 |
3 | import android.widget.TextView;
4 |
5 | /**
6 | * Created by zhaolei on 2017/8/15.
7 | */
8 |
9 | public interface TxtShader2 {
10 |
11 | void onShade(TextView textView);
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/java/drawn/lltvcn/com/textdemo/TxtShader2Ext.java:
--------------------------------------------------------------------------------
1 | package drawn.lltvcn.com.textdemo;
2 |
3 | import android.widget.TextView;
4 |
5 | /**
6 | * Created by zhaolei on 2017/8/17.
7 | */
8 |
9 | public abstract class TxtShader2Ext implements TxtShader2{
10 |
11 |
12 | private ParamProvider paramProvider;
13 |
14 |
15 | public final ParamProvider getParamProvider(){
16 | if(paramProvider==null){
17 | paramProvider = new ParamProviderImpl();
18 | }
19 | return paramProvider;
20 | }
21 |
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/java/drawn/lltvcn/com/textdemo/controller/EditTxtController.java:
--------------------------------------------------------------------------------
1 | package drawn.lltvcn.com.textdemo.controller;
2 |
3 | import android.content.Context;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.view.animation.Animation;
8 | import android.view.animation.TranslateAnimation;
9 | import android.view.inputmethod.InputMethodManager;
10 | import android.widget.EditText;
11 |
12 | import drawn.lltvcn.com.textdemo.R;
13 |
14 | /**
15 | * Created by zhaolei on 2017/10/13.
16 | */
17 |
18 | public class EditTxtController {
19 |
20 | private View view;
21 | private EditText et;
22 | private ViewGroup parent;
23 |
24 |
25 | public void init(ViewGroup parent){
26 | this.parent = parent;
27 | this.view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_edit_txt,parent,false);
28 | parent.addView(view);
29 | view.setVisibility(View.GONE);
30 | et = (EditText) view.findViewById(R.id.et_edit);
31 | view.findViewById(R.id.btn_et_confirm).setOnClickListener(new View.OnClickListener() {
32 | @Override
33 | public void onClick(View v) {
34 | if (confirmListener!=null){
35 | confirmListener.onConfirm(et.getText().toString());
36 | }
37 | dismiss();
38 | }
39 | });
40 | view.findViewById(R.id.btn_et_cancel).setOnClickListener(new View.OnClickListener() {
41 | @Override
42 | public void onClick(View v) {
43 | dismiss();
44 | }
45 | });
46 | }
47 |
48 | public interface OnConfirmListener{
49 | void onConfirm(String content);
50 | }
51 |
52 | OnConfirmListener confirmListener;
53 | public void show(OnConfirmListener confirmListener){
54 | view.setVisibility(View.VISIBLE);
55 | parent.setVisibility(View.VISIBLE);
56 | et.setText(null);
57 | this.confirmListener = confirmListener;
58 | TranslateAnimation ta = new TranslateAnimation(Animation.RELATIVE_TO_SELF,0f,Animation.RELATIVE_TO_SELF,0f,Animation.RELATIVE_TO_SELF,-1,Animation.RELATIVE_TO_SELF,0);
59 | ta.setDuration(400);
60 | view.startAnimation(ta);
61 | view.postDelayed(new Runnable() {
62 | @Override
63 | public void run() {
64 | et.requestFocus();
65 | InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
66 | imm.showSoftInput(et,InputMethodManager.SHOW_IMPLICIT);
67 | }
68 | },400);
69 | }
70 |
71 | public void dismiss(){
72 | TranslateAnimation ta = new TranslateAnimation(Animation.RELATIVE_TO_SELF,0f,Animation.RELATIVE_TO_SELF,0f,Animation.RELATIVE_TO_SELF,0,Animation.RELATIVE_TO_SELF,-1);
73 | ta.setDuration(400);
74 | ta.setAnimationListener(new Animation.AnimationListener() {
75 | @Override
76 | public void onAnimationStart(Animation animation) {
77 |
78 | }
79 |
80 | @Override
81 | public void onAnimationEnd(Animation animation) {
82 | view.setVisibility(View.GONE);
83 | dismissParent();
84 | }
85 |
86 | @Override
87 | public void onAnimationRepeat(Animation animation) {
88 |
89 | }
90 | });
91 | view.startAnimation(ta);
92 | InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
93 | imm.hideSoftInputFromWindow(et.getWindowToken(),InputMethodManager.HIDE_NOT_ALWAYS);
94 | }
95 |
96 |
97 | private void dismissParent(){
98 | for (int i = 0; i < parent.getChildCount(); i++) {
99 | if(parent.getChildAt(i).getVisibility() == View.VISIBLE){
100 | return;
101 | }
102 | }
103 | parent.setVisibility(View.GONE);
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/app/src/main/java/drawn/lltvcn/com/textdemo/controller/SelectController.java:
--------------------------------------------------------------------------------
1 | package drawn.lltvcn.com.textdemo.controller;
2 |
3 | import android.support.v7.widget.LinearLayoutManager;
4 | import android.support.v7.widget.RecyclerView;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.view.animation.Animation;
9 | import android.view.animation.TranslateAnimation;
10 | import android.widget.CheckBox;
11 |
12 | import java.util.ArrayList;
13 |
14 | import drawn.lltvcn.com.textdemo.R;
15 |
16 | /**
17 | * Created by zhaolei on 2017/10/17.
18 | */
19 |
20 | public class SelectController {
21 |
22 | private ViewGroup parent;
23 | private View view;
24 | private RecyclerView rv;
25 | public String[] data;
26 | private MyAdapter adapter = new MyAdapter();
27 |
28 | private EditParamViewController.VisiableListener listener;
29 |
30 | public void init(ViewGroup parent, EditParamViewController.VisiableListener listener){
31 | this.parent = parent;
32 | this.listener = listener;
33 | view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_edit_v2,parent,false);
34 | parent.addView(view);
35 | rv = (RecyclerView) findViewById(R.id.rv);
36 | rv.setAdapter(adapter);
37 | rv.setLayoutManager(new LinearLayoutManager(view.getContext(),LinearLayoutManager.VERTICAL,false));
38 | // rv.setLayoutManager(new GridLayoutManager(parent.getContext(),3, LinearLayoutManager.HORIZONTAL,false));
39 | findViewById(R.id.btn_confirm).setOnClickListener(new View.OnClickListener() {
40 | @Override
41 | public void onClick(View v) {
42 | ArrayList result = new ArrayList();
43 | for (int i = 0; i < rv.getChildCount(); i++) {
44 | CheckBox ck = (CheckBox) rv.getChildAt(i).findViewById(R.id.ck);
45 | if(ck.isChecked()){
46 | result.add(data[i]);
47 | }
48 | }
49 | resultLis.onConfrim(result);
50 | dismiss();
51 | }
52 | });
53 | findViewById(R.id.btn_cancel).setOnClickListener(new View.OnClickListener() {
54 | @Override
55 | public void onClick(View v) {
56 | dismiss();
57 | }
58 | });
59 | }
60 |
61 | private View findViewById(int id){
62 | return view.findViewById(id);
63 | }
64 |
65 | private class MyAdapter extends RecyclerView.Adapter{
66 |
67 | @Override
68 | public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
69 | return new Holder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_ck,parent,false));
70 | }
71 |
72 | @Override
73 | public void onBindViewHolder(Holder holder, int position) {
74 | String content = data[position];
75 | holder.ck.setText(content);
76 | }
77 |
78 | @Override
79 | public int getItemCount() {
80 | return data==null?0:data.length;
81 | }
82 | }
83 |
84 | private CheckBox lastCK;
85 | private boolean isMulti;
86 |
87 | private class Holder extends RecyclerView.ViewHolder{
88 | private CheckBox ck;
89 |
90 | public Holder(View itemView) {
91 | super(itemView);
92 | ck = (CheckBox) itemView.findViewById(R.id.ck);
93 | ck.setChecked(false);
94 | ck.setClickable(false);
95 | ck.setFocusable(false);
96 | itemView.setOnClickListener(new View.OnClickListener() {
97 | @Override
98 | public void onClick(View v) {
99 | ArrayList str = new ArrayList();
100 | str.add(data[rv.getChildAdapterPosition(v)]);
101 | resultLis.onConfrim(str);
102 | dismiss();
103 | }
104 | });
105 | // ck.setOnClickListener(new View.OnClickListener() {
106 | // @Override
107 | // public void onClick(View v) {
108 | // if(!isMulti){
109 | // if(ck.isChecked()){
110 | // if(lastCK!=null&&lastCK!=ck){
111 | // lastCK.setChecked(false);
112 | // }
113 | // lastCK = ck;
114 | // }
115 | // }
116 | //
117 | // }
118 | // });
119 | }
120 | }
121 |
122 | public interface ResultListener{
123 | void onConfrim(ArrayList result);
124 | }
125 |
126 | private ResultListener resultLis;
127 | public void show(String[] data,boolean isMulti,ResultListener listener){
128 | this.resultLis = listener;
129 | this.data = data;
130 | this.isMulti = isMulti;
131 | adapter.notifyDataSetChanged();
132 | show();
133 | }
134 |
135 | public void show(){
136 | view.setVisibility(View.VISIBLE);
137 | parent.setVisibility(View.VISIBLE);
138 | TranslateAnimation ta = new TranslateAnimation(Animation.RELATIVE_TO_SELF,0f,Animation.RELATIVE_TO_SELF,0f,Animation.RELATIVE_TO_SELF,1,Animation.RELATIVE_TO_SELF,0);
139 | ta.setDuration(400);
140 | view.startAnimation(ta);
141 | listener.onVisable(true);
142 | }
143 |
144 | public void dismiss(){
145 | lastCK = null;
146 | TranslateAnimation ta = new TranslateAnimation(Animation.RELATIVE_TO_SELF,0f,Animation.RELATIVE_TO_SELF,0f,Animation.RELATIVE_TO_SELF,0,Animation.RELATIVE_TO_SELF,1);
147 | ta.setDuration(400);
148 | ta.setAnimationListener(new Animation.AnimationListener() {
149 | @Override
150 | public void onAnimationStart(Animation animation) {
151 |
152 | }
153 |
154 | @Override
155 | public void onAnimationEnd(Animation animation) {
156 | view.setVisibility(View.GONE);
157 | listener.onVisable(false);
158 | dismissParent();
159 | }
160 |
161 | @Override
162 | public void onAnimationRepeat(Animation animation) {
163 |
164 | }
165 | });
166 | view.startAnimation(ta);
167 | }
168 |
169 | private void dismissParent(){
170 | for (int i = 0; i < parent.getChildCount(); i++) {
171 | if(parent.getChildAt(i).getVisibility() == View.VISIBLE){
172 | return;
173 | }
174 | }
175 | parent.setVisibility(View.GONE);
176 | }
177 |
178 |
179 | }
180 |
--------------------------------------------------------------------------------
/app/src/main/java/drawn/lltvcn/com/textdemo/data/BgData.java:
--------------------------------------------------------------------------------
1 | package drawn.lltvcn.com.textdemo.data;
2 |
3 | import com.lltvcn.freefont.core.annotation.Description;
4 | import com.lltvcn.freefont.core.annotation.Img;
5 |
6 | /**
7 | * Created by zhaolei on 2017/10/18.
8 | */
9 |
10 | public class BgData {
11 |
12 | @Description(name = "背景图",cls = Img.class)
13 | public String bitmap;
14 |
15 | @Description(name = "背景色")
16 | public String bgColor;
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/drawn/lltvcn/com/textdemo/data/FontData.java:
--------------------------------------------------------------------------------
1 | package drawn.lltvcn.com.textdemo.data;
2 |
3 | import java.util.HashMap;
4 |
5 | import com.lltvcn.freefont.core.data.DrawData;
6 |
7 | /**
8 | * Created by zhaolei on 2017/10/18.
9 | */
10 |
11 | public class FontData {
12 |
13 | public DrawData drawData;
14 |
15 | public HashMap dependImgs;
16 |
17 | public HashMap dependFonts;
18 | }
19 |
--------------------------------------------------------------------------------
/app/src/main/java/drawn/lltvcn/com/textdemo/data/FontStyleData.java:
--------------------------------------------------------------------------------
1 | package drawn.lltvcn.com.textdemo.data;
2 |
3 | import com.lltvcn.freefont.core.annotation.Description;
4 | import com.lltvcn.freefont.core.layer.FontStyle;
5 |
6 | /**
7 | * Created by zhaolei on 2017/10/18.
8 | */
9 |
10 | public class FontStyleData {
11 |
12 | @Description(name = "字体风格")
13 | public FontStyle fontStyle;
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/java/drawn/lltvcn/com/util/FontUtil.java:
--------------------------------------------------------------------------------
1 | package drawn.lltvcn.com.util;
2 |
3 | import android.content.Context;
4 | import android.graphics.Typeface;
5 |
6 | import java.io.IOException;
7 |
8 | import drawn.lltvcn.com.textdemo.MainApplication;
9 |
10 | /**
11 | * Created by zhaolei on 2018/1/4.
12 | */
13 |
14 | public class FontUtil {
15 |
16 | private static Context context = MainApplication.getInstance();
17 | private static String[] assetFonts,fileFonts,result;
18 |
19 | static {
20 | fileFonts = FileUtil.getFontNames();
21 | try {
22 | assetFonts = context.getAssets().list("ttf");
23 | } catch (IOException e) {
24 | e.printStackTrace();
25 | }
26 | int length = 0;
27 | if(fileFonts!=null){
28 | length += fileFonts.length;
29 | }
30 | if(assetFonts!=null){
31 | length += assetFonts.length;
32 | }
33 | result = new String[length];
34 | int index = 0;
35 | if(fileFonts!=null){
36 | System.arraycopy(fileFonts,0,result,0,fileFonts.length);
37 | index += fileFonts.length;
38 | }
39 | if(assetFonts!=null){
40 | System.arraycopy(assetFonts,0,result,index,assetFonts.length);
41 | }
42 | }
43 |
44 | public static String[] getFontNames(){
45 | return result;
46 | }
47 |
48 | public static Typeface getTypeface(String name){
49 | if(contain(fileFonts,name)){
50 | return Typeface.createFromFile(FileUtil.getFontPath(name));
51 | }else if(contain(assetFonts,name)){
52 | return Typeface.createFromAsset(context.getAssets(),"ttf/"+name);
53 | }else {
54 | return null;
55 | }
56 | }
57 |
58 | private static boolean contain(String[] strs,String name){
59 | if(strs==null||strs.length==0)
60 | return false;
61 | for (String str :
62 | strs) {
63 | if(str.equals(name))
64 | return true;
65 | }
66 | return false;
67 | }
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/app/src/main/java/drawn/lltvcn/com/util/SUtil.java:
--------------------------------------------------------------------------------
1 | package drawn.lltvcn.com.util;
2 |
3 | import java.util.Random;
4 |
5 | /**
6 | * Created by zhaolei on 2018/1/5.
7 | */
8 |
9 | public class SUtil {
10 |
11 | private static Random random = new Random(500);
12 | private static String[] strs;
13 |
14 | static {
15 | strs = new String[]{
16 | "人生若只如初见,何事秋风悲画扇。",
17 | "我来不及认真地年轻,待明白过来时,只能选择认真地老去。",
18 | "人生本来如此:喜欢的事自然可以坚持,不喜欢的怎么也长久不了。",
19 | "愿时光如玉,别有温润,滚滚凡尘,浮生尽欢",
20 | "今天会很残酷,明天会更残酷"
21 | };
22 | }
23 |
24 | public static String getTxt(){
25 | return strs[random.nextInt(strs.length)];
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/main/java/drawn/lltvcn/com/util/ZipUtil.java:
--------------------------------------------------------------------------------
1 | package drawn.lltvcn.com.util;
2 |
3 | import java.io.BufferedInputStream;
4 | import java.io.BufferedOutputStream;
5 | import java.io.File;
6 | import java.io.FileInputStream;
7 | import java.io.FileNotFoundException;
8 | import java.io.FileOutputStream;
9 | import java.io.IOException;
10 | import java.io.InputStream;
11 | import java.util.zip.ZipEntry;
12 | import java.util.zip.ZipInputStream;
13 | import java.util.zip.ZipOutputStream;
14 |
15 | public class ZipUtil {
16 |
17 | public static boolean decompress(String zipFilePath,String aimDir,boolean deleteOld){
18 | try {
19 | return decompress(new FileInputStream(zipFilePath), aimDir, deleteOld);
20 | } catch (FileNotFoundException e) {
21 | e.printStackTrace();
22 | return false;
23 | }
24 | }
25 |
26 | public static boolean decompress(InputStream inputStream ,String aimDir,boolean deleteOld){
27 | long startTime=System.currentTimeMillis();
28 | try {
29 | ZipInputStream Zin=new ZipInputStream(inputStream);//输入源zip路径
30 | BufferedInputStream Bin=new BufferedInputStream(Zin);
31 | File Fout=null;
32 | ZipEntry entry;
33 | File file = new File(aimDir);
34 | if(!file.exists()){
35 | file.mkdirs();
36 | }else{
37 | if(deleteOld){
38 | file.delete();
39 | file.mkdirs();
40 | }
41 | }
42 |
43 | while((entry = Zin.getNextEntry())!=null){
44 | if(entry.isDirectory()) {
45 | continue;
46 | }
47 | Fout=new File(aimDir,entry.getName());
48 | if(!Fout.exists()){
49 | (new File(Fout.getParent())).mkdirs();
50 | }
51 | FileOutputStream out=new FileOutputStream(Fout);
52 | BufferedOutputStream Bout=new BufferedOutputStream(out);
53 | int b;
54 | while((b=Bin.read())!=-1){
55 | Bout.write(b);
56 | }
57 | Bout.close();
58 | out.close();
59 | System.out.println(Fout+"解压成功");
60 | }
61 | Bin.close();
62 | Zin.close();
63 | long endTime=System.currentTimeMillis();
64 | System.out.println("耗费时间: "+(endTime-startTime)+" ms");
65 | return true;
66 | } catch (Exception e) {
67 | e.printStackTrace();
68 | return false;
69 | }
70 | }
71 |
72 | /**
73 | * 将存放在sourceFilePath目录下的源文件,打包成fileName名称的zip文件,并存放到zipFilePath路径下
74 | * @param sourceFilePath :待压缩的文件路径
75 | * @param zipFilePath :压缩后存放路径
76 | * @param fileName :压缩后文件的名称
77 | * @return
78 | */
79 | public static boolean compress(String sourceFilePath,String zipFilePath,String fileName){
80 | boolean flag = false;
81 | File sourceFile = new File(sourceFilePath);
82 | FileInputStream fis = null;
83 | BufferedInputStream bis = null;
84 | FileOutputStream fos = null;
85 | ZipOutputStream zos = null;
86 |
87 | if(sourceFile.exists() == false){
88 | System.out.println("待压缩的文件目录:"+sourceFilePath+"不存在.");
89 | }else{
90 | try {
91 | File zipFile = new File(zipFilePath + "/" + fileName +".zip");
92 | if(zipFile.exists()){
93 | System.out.println(zipFilePath + "目录下存在名字为:" + fileName +".zip" +"打包文件.");
94 | }else{
95 | File[] sourceFiles = sourceFile.listFiles();
96 | if(null == sourceFiles || sourceFiles.length<1){
97 | System.out.println("待压缩的文件目录:" + sourceFilePath + "里面不存在文件,无需压缩.");
98 | }else{
99 | fos = new FileOutputStream(zipFile);
100 | zos = new ZipOutputStream(new BufferedOutputStream(fos));
101 | byte[] bufs = new byte[1024*10];
102 | for(int i=0;i
2 |
9 |
10 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
31 |
32 |
41 |
42 |
46 |
47 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_array.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
18 |
19 |
24 |
25 |
30 |
31 |
36 |
37 |
38 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_ck.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_demo.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
17 |
18 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_enum.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
12 |
13 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_layer.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_normal.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
12 |
13 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_code.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_edit.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
20 |
21 |
22 |
27 |
28 |
29 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_edit_txt.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
16 |
17 |
23 |
24 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_edit_v2.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
16 |
17 |
23 |
24 |
30 |
31 |
32 |
33 |
34 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
11 |
12 |
17 |
18 |
23 |
24 |
29 |
30 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_review.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
17 |
18 |
23 |
24 |
29 |
30 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_review_ani.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
16 |
17 |
22 |
23 |
28 |
29 |
34 |
35 |
36 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_scroll.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
16 |
17 |
23 |
24 |
30 |
31 |
37 |
38 |
44 |
45 |
50 |
51 |
57 |
58 |
64 |
65 |
71 |
72 |
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lltvcn/FreeText/d8d6daa5bb6872017e04b7f72f3e54b239a16798/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lltvcn/FreeText/d8d6daa5bb6872017e04b7f72f3e54b239a16798/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lltvcn/FreeText/d8d6daa5bb6872017e04b7f72f3e54b239a16798/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lltvcn/FreeText/d8d6daa5bb6872017e04b7f72f3e54b239a16798/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lltvcn/FreeText/d8d6daa5bb6872017e04b7f72f3e54b239a16798/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | TextDemo
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/drawn/lltvcn/com/textdemo/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package drawn.lltvcn.com.textdemo;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.2.2'
9 | // NOTE: Do not place your application dependencies here; they belong
10 | // in the individual module build.gradle files
11 | }
12 | }
13 |
14 | allprojects {
15 | repositories {
16 | jcenter()
17 | }
18 | }
19 |
20 | task clean(type: Delete) {
21 | delete rootProject.buildDir
22 | }
23 |
--------------------------------------------------------------------------------
/freefont/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/freefont/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 25
5 | buildToolsVersion "26.0.0"
6 |
7 | defaultConfig {
8 | minSdkVersion 15
9 | targetSdkVersion 25
10 | versionCode 1
11 | versionName "1.0"
12 |
13 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
14 |
15 | }
16 | buildTypes {
17 | release {
18 | minifyEnabled false
19 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
20 | }
21 | }
22 | }
23 |
24 | dependencies {
25 | compile fileTree(include: ['*.jar'], dir: 'libs')
26 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
27 | exclude group: 'com.android.support', module: 'support-annotations'
28 | })
29 | compile 'com.android.support:appcompat-v7:25.3.1'
30 | testCompile 'junit:junit:4.12'
31 | }
32 |
--------------------------------------------------------------------------------
/freefont/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/zhaolei/Documents/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/freefont/src/androidTest/java/com/lltvcn/freefont/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumentation test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.lltvcn.freefont.test", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/freefont/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/animation/Animation2IA.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.animation;
2 |
3 | import android.view.animation.Animation;
4 |
5 | /**
6 | * Created by zhaolei on 2017/12/6.
7 | */
8 |
9 | public class Animation2IA implements TA {
10 | private Animation animation;
11 |
12 | public Animation2IA(Animation animation){
13 | this.animation = animation;
14 | }
15 |
16 | @Override
17 | public void start() {
18 | animation.start();
19 | }
20 |
21 | @Override
22 | public void stop() {
23 | animation.cancel();
24 | }
25 |
26 |
27 | @Override
28 | public long getDuration() {
29 | return animation.getDuration();
30 | }
31 |
32 | @Override
33 | public Animation getValue() {
34 | return animation;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/animation/AnimationQueen.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.animation;
2 |
3 | import android.view.animation.Animation;
4 | import android.widget.TextView;
5 |
6 | import java.util.ArrayList;
7 |
8 | /**
9 | * Created by zhaolei on 2017/12/6.
10 | */
11 |
12 | public class AnimationQueen extends Animation{
13 | private ArrayList animations = new ArrayList<>();
14 | private TextView tv;
15 | private Animation currentAnimation;
16 | private int currentIndex;
17 | private int repeatCount;
18 |
19 | public AnimationQueen (TextView tv){
20 | this.tv = tv;
21 | }
22 |
23 |
24 | public AnimationQueen addAnimation(Animation animation){
25 | animations.add(animation);
26 | animation.setAnimationListener(listener);
27 | return this;
28 | }
29 |
30 |
31 | @Override
32 | public void start() {
33 | if(currentAnimation!=null){
34 | cancel();
35 | tv.post(new Runnable() {
36 | @Override
37 | public void run() {
38 | start();
39 | }
40 | });
41 | return;
42 | }
43 | currentAnimation = animations.get(0);
44 | currentIndex = 0;
45 | repeatCount = 0;
46 | if(currentAnimation!=null){
47 | tv.setAnimation(currentAnimation);
48 | currentAnimation.start();
49 | }
50 | }
51 |
52 |
53 | @Override
54 | public void cancel() {
55 | if(currentAnimation!=null&¤tAnimation.hasStarted()){
56 | Animation animation = currentAnimation;
57 | currentAnimation = null;
58 | currentIndex = 0;
59 | animation.cancel();
60 | }
61 | currentAnimation = null;
62 | currentIndex = 0;
63 | repeatCount = 0;
64 | }
65 |
66 | @Override
67 | public long getDuration() {
68 | long duration = 0;
69 | for (Animation animation :
70 | animations) {
71 | if(animation.getRepeatCount()!=INFINITE){
72 | duration += animation.getRepeatCount()*animation.getDuration();
73 | }else {
74 | return INFINITE;
75 | }
76 | }
77 | return duration;
78 | }
79 |
80 | private AnimationListener listener = new AnimationListener() {
81 | @Override
82 | public void onAnimationStart(Animation animation) {
83 |
84 | }
85 |
86 | @Override
87 | public void onAnimationEnd(Animation animation) {
88 | if(currentAnimation!=null){
89 | boolean start = false;
90 | if(currentIndex == animations.size()-1){
91 | repeatCount++;
92 | if(getRepeatCount() == INFINITE||repeatCount<=getRepeatCount()){
93 | currentIndex = 0;
94 | start = true;
95 | }else{
96 | start = false;
97 | repeatCount = 0;
98 | currentIndex = 0;
99 | currentAnimation = null;
100 | }
101 | }else if(currentIndex{
13 | private BaseAnimation animator;
14 |
15 | public BaseAnimation2IA(BaseAnimation animator){
16 | this.animator = animator;
17 | }
18 |
19 | @Override
20 | public void start() {
21 | animator.start();
22 | }
23 |
24 | @Override
25 | public void stop() {
26 | animator.end();
27 | }
28 |
29 | @Override
30 | public long getDuration() {
31 | return animator.getDuration();
32 | }
33 |
34 | @Override
35 | public BaseAnimation getValue() {
36 | return animator;
37 | }
38 |
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/animation/ICanvasTransform.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.animation;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Paint;
5 | import android.graphics.RectF;
6 |
7 | /**
8 | * Created by zhaolei on 2017/12/4.
9 | */
10 |
11 | public interface ICanvasTransform {
12 |
13 | void transformCanvas(int index , RectF rect, Canvas canvas, Paint paint);
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/animation/TA.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.animation;
2 |
3 | public interface TA {
4 | void start();
5 |
6 | void stop();
7 |
8 | long getDuration();
9 |
10 | T getValue();
11 | }
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/animation/TAnimation.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.animation;
2 |
3 | import android.animation.ValueAnimator;
4 | import android.graphics.Canvas;
5 | import android.graphics.Matrix;
6 | import android.graphics.Paint;
7 | import android.graphics.RectF;
8 | import android.util.Log;
9 | import android.widget.TextView;
10 |
11 | /**
12 | * Created by zhaolei on 2017/12/4.
13 | */
14 |
15 | public class TAnimation extends BaseAnimation {
16 |
17 |
18 | private long itemDuration = 400;
19 | private float fromX,toX,fromY,toY,fromAlpha,toAlpha,fromScaleX,toScaleX,fromScaleY,toScaleY,fromDegree,toDegree;
20 | private boolean hasAlpha,hasTranslate,hasRotate,hasScale;
21 | private ValueComputer valueComputer;
22 | private Matrix matrix = new Matrix();
23 |
24 |
25 | public TAnimation(TextView tv) {
26 | super(tv);
27 | }
28 |
29 | @Deprecated
30 | @Override
31 | public ValueAnimator setDuration(long duration) {
32 | return this;
33 | }
34 |
35 |
36 | @Override
37 | public long getDuration() {
38 | checkDuration();
39 | return super.getDuration();
40 | }
41 |
42 |
43 | @Override
44 | public void start() {
45 | checkDuration();
46 | super.start();
47 | }
48 |
49 | @Override
50 | public void reverse() {
51 | checkDuration();
52 | super.reverse();
53 | }
54 |
55 | public void setItemDuration(long duration){
56 | itemDuration = duration;
57 | }
58 |
59 |
60 | private void checkDuration(){
61 | long duration = valueComputer.getDuration(tv.getText().length(),this);
62 | if(duration != super.getDuration()){
63 | super.setDuration(duration);
64 | }
65 | }
66 |
67 | public static class Builder{
68 | TAnimation a;
69 |
70 | public Builder(TextView tv){
71 | a = new TAnimation(tv);
72 | }
73 |
74 | public Builder itemDuration(long duration){
75 | a.itemDuration = duration;
76 | return this;
77 | }
78 |
79 | public Builder alpha(float from,float to){
80 | a.hasAlpha = true;
81 | a.fromAlpha = from;
82 | a.toAlpha = to;
83 | return this;
84 | }
85 |
86 | public Builder translate(float fromX,float toX,float fromY,float toY){
87 | a.hasTranslate = true;
88 | a.fromX = fromX;
89 | a.toX = toX;
90 | a.fromY = fromY;
91 | a.toY = toY;
92 | return this;
93 | }
94 |
95 |
96 | public Builder scale(float fromX,float toX,float fromY,float toY){
97 | a.fromScaleX = fromX;
98 | a.toScaleX = toX;
99 | a.fromScaleY = fromY;
100 | a.toScaleY = toY;
101 | a.hasScale = true;
102 | return this;
103 | }
104 |
105 | public Builder rotate(float from,float to){
106 | a.hasRotate = true;
107 | a.fromDegree = from;
108 | a.toDegree = to;
109 | return this;
110 | }
111 |
112 | public Builder valueComputer(ValueComputer computer){
113 | a.valueComputer = computer;
114 | return this;
115 | }
116 |
117 | public TAnimation create(){
118 | return a;
119 | }
120 |
121 | }
122 |
123 |
124 | public interface ValueComputer{
125 | float getVlaue(int index,TAnimation animation);
126 |
127 | long getDuration(int count,TAnimation animation);
128 | }
129 |
130 |
131 |
132 | @Override
133 | public void transformCanvas(int index, RectF rect, Canvas canvas, Paint paint) {
134 | if(valueComputer!=null){
135 | float value = valueComputer.getVlaue(index,this);
136 | if(valueComputer instanceof SquenceComputer&&(value==0||value == 1)){
137 | if((int) (255*(fromAlpha+value*(toAlpha-fromAlpha))) == 255){
138 | Log.i("jisisos","value="+value+"index------"+index+"-----"+getCurrentPlayTime()+"::::");
139 | }
140 | }
141 | if(hasAlpha){
142 | paint.setAlpha((int) (255*(fromAlpha+value*(toAlpha-fromAlpha))));
143 | }
144 | matrix.reset();
145 | boolean needTransform = false;
146 | if(hasRotate){
147 | needTransform = true;
148 | matrix.setRotate((fromDegree+value*(toDegree-fromDegree)),rect.centerX(),rect.centerY());
149 | }
150 | if(hasScale){
151 | needTransform = true;
152 | matrix.postScale((fromScaleX+value*(toScaleX-fromScaleX)),(fromScaleY+value*(toScaleY-fromScaleY)),rect.centerX(),rect.centerY());
153 | }
154 | if(hasTranslate){
155 | needTransform = true;
156 | matrix.postTranslate(rect.width()*(fromX+value*(toX-fromX)),rect.height()*(fromY+value*(toY-fromY)));
157 | }
158 | if(needTransform){
159 | canvas.concat(matrix);
160 | }
161 | }
162 | }
163 |
164 | public static ValueComputer SAME = new ValueComputer() {
165 | @Override
166 | public float getVlaue(int index, TAnimation animation) {
167 | return (float) animation.getAnimatedValue();
168 | }
169 |
170 | @Override
171 | public long getDuration(int count, TAnimation animation) {
172 | return animation.itemDuration;
173 | }
174 | };
175 |
176 | public static ValueComputer NEG = new ValueComputer() {
177 | @Override
178 | public float getVlaue(int index, TAnimation animation) {
179 | if(index%2==0){
180 | return (float)animation.getAnimatedValue();
181 | }else{
182 | return -(float)animation.getAnimatedValue();
183 | }
184 | }
185 |
186 | @Override
187 | public long getDuration(int count,TAnimation animation) {
188 | return animation.itemDuration;
189 | }
190 | };
191 |
192 | public static ValueComputer REVERSE = new ValueComputer() {
193 | @Override
194 | public float getVlaue(int index, TAnimation animation) {
195 | if(index%2==0){
196 | return (float)animation.getAnimatedValue();
197 | }else{
198 | return 1-(float)animation.getAnimatedValue();
199 | }
200 | }
201 |
202 | @Override
203 | public long getDuration(int count,TAnimation animation) {
204 | return animation.itemDuration;
205 | }
206 | };
207 |
208 | public static class SquenceComputer implements ValueComputer{
209 | private long offsetDuration;
210 |
211 | public SquenceComputer(long offset){
212 | offsetDuration = offset;
213 | }
214 |
215 | @Override
216 | public float getVlaue(int index, TAnimation animation) {
217 | float duration = animation.getCurrentPlayTime()-(offsetDuration*index);
218 | if(animation.isRunning()){
219 | if (duration>0&&duration animations = new ArrayList<>();
23 | private Field fRunning;
24 |
25 | public TAnimationQueen(TextView tv) {
26 | super(tv);
27 | try {
28 | fRunning = ValueAnimator.class.getDeclaredField("mRunning");
29 | } catch (NoSuchFieldException e) {
30 | e.printStackTrace();
31 | }
32 | }
33 |
34 | public void addAnimation(BaseAnimation animation){
35 | if(!animations.contains(animation)){
36 | animations.add(animation);
37 | }
38 | }
39 |
40 | @Deprecated
41 | @Override
42 | public ValueAnimator setDuration(long duration) {
43 | return this;
44 | }
45 |
46 |
47 | @Override
48 | public long getDuration() {
49 | checkDuration();
50 | return super.getDuration();
51 | }
52 |
53 | @Override
54 | public void start() {
55 | checkDuration();
56 | super.start();
57 | fRunning.setAccessible(true);
58 | for (BaseAnimation animation:animations) {
59 | try {
60 | fRunning.setBoolean(animation,true);
61 | } catch (IllegalAccessException e) {
62 | e.printStackTrace();
63 | }
64 | }
65 | fRunning.setAccessible(false);
66 | }
67 |
68 | private void checkDuration(){
69 | long duration = 0;
70 | for (BaseAnimation animation:animations) {
71 | duration += animation.getDuration();
72 | }
73 | if(duration!=super.getDuration()){
74 | super.setDuration(duration);
75 | }
76 | }
77 |
78 | @Override
79 | public void reverse() {
80 | checkDuration();
81 | super.reverse();
82 | }
83 |
84 | @Override
85 | public void end() {
86 | super.end();
87 | for (BaseAnimation animation:animations) {
88 | fRunning.setAccessible(true);
89 | try {
90 | fRunning.setBoolean(animation,false);
91 | } catch (IllegalAccessException e) {
92 | e.printStackTrace();
93 | }
94 | fRunning.setAccessible(false);
95 | }
96 | }
97 |
98 |
99 | @Override
100 | public void transformCanvas(int index, RectF rect, Canvas canvas, Paint paint) {
101 | long currentTime = (long) ((Float)getAnimatedValue()*getDuration());
102 | long time = 0;
103 | long duration;
104 | boolean hasTrans = false;
105 | for (BaseAnimation animation:animations) {
106 | duration = animation.getDuration();
107 | if(time<=currentTime&&time+duration>currentTime){
108 | hasTrans = true;
109 | Log.i("kkais","currentTime:"+currentTime+"duration:"+duration+"::time"+time);
110 | animation.setCurrentPlayTime(currentTime-time);
111 | animation.transformCanvas(index,rect,canvas,paint);
112 | break;
113 | }
114 | time+=duration;
115 | }
116 | if(!hasTrans){
117 | Log.i("ddsiis","no");
118 | }
119 | }
120 |
121 |
122 | }
123 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/animation/TAnimationSet.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.animation;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Paint;
5 | import android.graphics.RectF;
6 | import android.widget.TextView;
7 |
8 | import java.util.ArrayList;
9 |
10 | /**
11 | * Created by zhaolei on 2017/12/7.
12 | */
13 |
14 | public class TAnimationSet extends BaseAnimation{
15 | private ArrayList animations = new ArrayList<>();
16 |
17 |
18 | public TAnimationSet(TextView tv) {
19 | super(tv);
20 | }
21 |
22 | public void addTAnimation(TAnimation animation){
23 | animations.add(animation);
24 | }
25 |
26 |
27 | @Override
28 | public void transformCanvas(int index, RectF rect, Canvas canvas, Paint paint) {
29 | for (TAnimation ani: animations) {
30 | ani.setCurrentPlayTime((long)((float)getAnimatedValue()*getDuration()));
31 | ani.transformCanvas(index,rect,canvas,paint);
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/annotation/Description.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * Created by zhaolei on 2017/10/16.
10 | */
11 | @Target(ElementType.FIELD)
12 | @Retention(RetentionPolicy.RUNTIME)
13 | public @interface Description {
14 |
15 | String name();
16 |
17 | Class cls() default Void.class;
18 | }
19 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/annotation/Font.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.annotation;
2 |
3 | /**
4 | * Created by zhaolei on 2017/10/17.
5 | */
6 |
7 | public interface Font {
8 | }
9 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/annotation/Img.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.annotation;
2 |
3 | /**
4 | * Created by zhaolei on 2017/10/17.
5 | */
6 |
7 | public interface Img {
8 |
9 |
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/data/AniData.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.data;
2 |
3 | import java.util.ArrayList;
4 | import java.util.HashMap;
5 |
6 | /**
7 | * Created by zhaolei on 2017/12/6.
8 | */
9 |
10 | public class AniData {
11 |
12 | public static final int TYPE_ALL = 0;
13 | public static final int TYPE_SINGLE_TXT = 1;
14 |
15 | public static final int MODE_SEQUENCE = 0;
16 |
17 | public int type;
18 |
19 | public Float fromX,toX,fromY,toY,fromAlpha,toAlpha,fromScaleX,toScaleX,fromScaleY,toScaleY,fromDegree,toDegree;
20 |
21 | public int aniMode;
22 |
23 | public HashMap aniParam;
24 |
25 | public long duration;
26 |
27 | public int repeatMode;
28 |
29 | public int repeatCount;
30 |
31 | public int startDelay;
32 |
33 | public ArrayList anis;
34 | }
35 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/data/BlurParam.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.data;
2 |
3 | import android.graphics.BlurMaskFilter;
4 |
5 | import com.lltvcn.freefont.core.annotation.Description;
6 |
7 | public class BlurParam{
8 |
9 | @Description(name = "半径")
10 | public float radius;
11 |
12 | @Description(name = "模糊方式",cls = BlurMaskFilter.Blur.class)
13 | public String blur;
14 | }
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/data/ClipParam.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.data;
2 |
3 | import com.lltvcn.freefont.core.annotation.Description;
4 |
5 | /**
6 | * Created by zhaolei on 2017/10/24.
7 | */
8 |
9 | public class ClipParam implements IDispatchDraw{
10 |
11 | @Description(name = "间隔高度")
12 | public float span;
13 |
14 | @Override
15 | public LayerData.DispatchDrawParam toDispatchDrawParam() {
16 | LayerData.DispatchDrawParam param = new LayerData.DispatchDrawParam();
17 | param.clipParam = this;
18 | return param;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/data/DrawData.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.data;
2 |
3 | import java.util.ArrayList;
4 |
5 | import com.lltvcn.freefont.core.annotation.Description;
6 | import com.lltvcn.freefont.core.annotation.Img;
7 |
8 |
9 | /**
10 | * Created by zhaolei on 2017/10/11.
11 | */
12 |
13 | public class DrawData {
14 |
15 | public ArrayList backLayers;
16 |
17 | public ArrayList foreLayers;
18 |
19 | public ArrayList layers;
20 |
21 | public Float width;
22 |
23 | public Float height;
24 |
25 | @Description(name = "图片名称",cls = Img.class)
26 | public String bgImg;
27 |
28 | @Description(name = "颜色")
29 | public String bgColor;
30 |
31 | public String fontStyle;
32 |
33 | public ShaderParam shaderParam;
34 |
35 | // public AniData aniData;
36 |
37 | public Integer aniType;
38 |
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/data/IDispatchDraw.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.data;
2 |
3 | /**
4 | * Created by zhaolei on 2017/10/24.
5 | */
6 |
7 | public interface IDispatchDraw {
8 |
9 | LayerData.DispatchDrawParam toDispatchDrawParam();
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/data/IShaderData.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.data;
2 |
3 | /**
4 | * Created by zhaolei on 2017/10/18.
5 | */
6 |
7 | public interface IShaderData {
8 |
9 | ShaderParam toShaderParam();
10 | }
11 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/data/IndexParam.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.data;
2 |
3 | import android.text.Spanned;
4 | import android.text.style.ForegroundColorSpan;
5 |
6 | import com.lltvcn.freefont.core.annotation.Description;
7 | import com.lltvcn.freefont.core.util.CU;
8 |
9 | import java.util.Random;
10 |
11 | /**
12 | * Created by zhaolei on 2017/10/18.
13 | */
14 |
15 | public class IndexParam {
16 |
17 | public enum Rule{
18 | Normal,Revert,Random
19 | }
20 |
21 | private transient static Random random = new Random(1000);
22 |
23 | @Description(name = "变化规则" ,cls = Rule.class)
24 | public String rule;
25 |
26 | public T[] datas;
27 |
28 | public boolean available(){
29 | return datas!=null&&datas.length>0;
30 | }
31 |
32 | public T getDataByIndex(int index){
33 | if(datas!=null){
34 | int length = datas.length;
35 | if(length==1){
36 | return datas[0];
37 | }else {
38 | switch (IndexParam.Rule.valueOf(rule)){
39 | case Random:
40 | return datas[random.nextInt(length)];
41 | case Normal:
42 | return datas[index%length];
43 | case Revert:
44 | if((index/length)%2 ==0){
45 | index = length-index%length-1;
46 | }else{
47 | index = index%length;
48 | }
49 | return datas[index];
50 | }
51 | }
52 | }
53 | return null;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/data/LayerData.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.data;
2 |
3 | import java.util.ArrayList;
4 |
5 | /**
6 | * Created by zhaolei on 2017/10/10.
7 | */
8 |
9 | public class LayerData {
10 |
11 | public static final int TYPE_MULTI = 2;
12 | public static final int TYPE_IMG = 1;
13 | public static final int TYPE_TXT = 0;
14 |
15 | public LayerData(){
16 |
17 | }
18 |
19 |
20 | /**
21 | * type: "img" , "txt","multi"*/
22 | public int type;
23 |
24 | public String name;
25 |
26 | public ArrayList layerDatas;
27 |
28 | public float offsetX,offsetY,degree,scale;
29 |
30 | public IndexParam imgs;
31 |
32 | public IndexParam colors;
33 |
34 | public PaintParam paintParam;
35 |
36 | public DispatchDrawParam drawParam;
37 |
38 | public static class DispatchDrawParam {
39 | public ClipParam clipParam;
40 | public OffsetParam offsetParam;
41 | }
42 |
43 | public static class PaintParam{
44 | public Float relativeSize;
45 | public String color;
46 | public IndexParam colors;
47 | public String font;
48 | public String fontStyle;
49 | public String style;
50 | public StokeParam stokeParam;
51 | public BlurParam blurParam;
52 | public ShaderParam shaderParam;
53 | public ShadowParam shadowParam;
54 | }
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/data/LineData.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.data;
2 |
3 | import android.graphics.Color;
4 |
5 | import com.lltvcn.freefont.core.linedrawer.Gravity;
6 | import com.lltvcn.freefont.core.annotation.Description;
7 | import com.lltvcn.freefont.core.annotation.Img;
8 |
9 | /**
10 | * Created by zhaolei on 2017/10/17.
11 | */
12 |
13 | public class LineData {
14 |
15 | @Description(name = "相对高度")
16 | public float rh;
17 |
18 | @Description(name = "位置" ,cls = Gravity.class)
19 | public String gravity;
20 |
21 | @Description(name = "图片名称",cls = Img.class)
22 | public String bitmap;
23 |
24 | @Description(name = "颜色" ,cls = Color.class)
25 | public Integer color;
26 | }
27 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/data/OffsetParam.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.data;
2 |
3 | import com.lltvcn.freefont.core.annotation.Description;
4 |
5 | /**
6 | * Created by zhaolei on 2017/10/24.
7 | */
8 |
9 | public class OffsetParam implements IDispatchDraw{
10 |
11 | @Description(name = "位置信息,与偏移量一一对应")
12 | public float[] positions;
13 |
14 | @Description(name = "每个位置的偏移量")
15 | public float[] offsets;
16 |
17 | @Override
18 | public LayerData.DispatchDrawParam toDispatchDrawParam() {
19 | LayerData.DispatchDrawParam param = new LayerData.DispatchDrawParam();
20 | param.offsetParam = this;
21 | return param;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/data/ShadeRadiusParam.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.data;
2 |
3 | import android.graphics.Shader;
4 |
5 | import com.lltvcn.freefont.core.annotation.Description;
6 |
7 | /**
8 | * Created by zhaolei on 2017/10/18.
9 | */
10 |
11 | public class ShadeRadiusParam implements IShaderData {
12 |
13 | @Description(name = "圆心水平相对坐标")
14 | public float centerX;
15 |
16 | @Description(name = "圆心竖直相对坐标")
17 | public float centerY;
18 |
19 | @Description(name = "半径")
20 | public float radius;
21 |
22 | @Description(name = "渐变颜色")
23 | public String[] colors;
24 |
25 | @Description(name = "渐变位置")
26 | public float[] positions;
27 |
28 | @Description(name = "重复模式" , cls = Shader.TileMode.class)
29 | public String tileMode;
30 |
31 | @Override
32 | public ShaderParam toShaderParam(){
33 | ShaderParam shaderParam = new ShaderParam();
34 | shaderParam.radiusParam = this;
35 | return shaderParam;
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/data/ShaderBitmapParam.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.data;
2 |
3 | import android.graphics.Shader;
4 |
5 | import com.lltvcn.freefont.core.annotation.Description;
6 | import com.lltvcn.freefont.core.annotation.Img;
7 |
8 | /**
9 | * Created by zhaolei on 2017/10/18.
10 | */
11 |
12 | public class ShaderBitmapParam implements IShaderData {
13 |
14 | @Description(name = "图片名称" ,cls = Img.class)
15 | public String img;
16 |
17 | @Description(name = "水平方向重复方式" ,cls = Shader.TileMode.class)
18 | public String tileModeX;
19 |
20 | @Description(name = "竖直方向重复方式" , cls = Shader.TileMode.class)
21 | public String tileModeY;
22 |
23 | // @Description(name = "图片高(默认为1,字体大小)")
24 | // public Float height;
25 | //
26 | // @Description(name = "图片宽(默认为1,字体大小)")
27 | // public Float width;
28 |
29 | @Override
30 | public ShaderParam toShaderParam(){
31 | ShaderParam shaderParam = new ShaderParam();
32 | shaderParam.bitmapParam = this;
33 | return shaderParam;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/data/ShaderLinearParam.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.data;
2 |
3 | import android.graphics.Shader;
4 |
5 | import com.lltvcn.freefont.core.annotation.Description;
6 |
7 | /**
8 | * Created by zhaolei on 2017/10/18.
9 | */
10 |
11 | public class ShaderLinearParam implements IShaderData {
12 |
13 | @Description(name = "起点水平相对坐标")
14 | public float x0;
15 |
16 | @Description(name = "终点水平相对坐标")
17 | public float x1;
18 |
19 | @Description(name = "起点竖直相对坐标")
20 | public float y0;
21 |
22 | @Description(name = "终点竖直相对坐标")
23 | public float y1;
24 |
25 | @Description(name = "渐变颜色")
26 | public String[] colors;
27 |
28 | @Description(name = "渐变位置")
29 | public float[] positions;
30 |
31 | @Description(name = "重复模式" ,cls = Shader.TileMode.class)
32 | public String tileMode;
33 |
34 | @Override
35 | public ShaderParam toShaderParam(){
36 | ShaderParam shaderParam = new ShaderParam();
37 | shaderParam.linearParam = this;
38 | return shaderParam;
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/data/ShaderParam.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.data;
2 |
3 | public class ShaderParam{
4 |
5 | public ShadeRadiusParam radiusParam;
6 | public ShaderBitmapParam bitmapParam;
7 | public ShaderLinearParam linearParam;
8 | public ShaderSweepParam sweepParam;
9 |
10 | }
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/data/ShaderSweepParam.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.data;
2 |
3 | import com.lltvcn.freefont.core.annotation.Description;
4 |
5 | /**
6 | * Created by zhaolei on 2017/10/18.
7 | */
8 |
9 | public class ShaderSweepParam implements IShaderData {
10 |
11 | @Description(name = "圆心X相对坐标")
12 | public float centerX;
13 |
14 | @Description(name = "圆心Y相对坐标")
15 | public float centerY;
16 |
17 | @Description(name = "渐变颜色")
18 | public String[] colors;
19 |
20 | @Description(name = "渐变位置")
21 | public float[] positions;
22 |
23 | @Override
24 | public ShaderParam toShaderParam(){
25 | ShaderParam shaderParam = new ShaderParam();
26 | shaderParam.sweepParam = this;
27 | return shaderParam;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/data/ShadowParam.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.data;
2 |
3 | import com.lltvcn.freefont.core.annotation.Description;
4 |
5 | public class ShadowParam{
6 |
7 | @Description(name = "半径")
8 | public float radius;
9 | @Description(name = "水平偏移")
10 | public float x;
11 | @Description(name = "竖直偏移")
12 | public float y;
13 | @Description(name = "阴影颜色")
14 | public String color;
15 |
16 |
17 | public ShadowParam(){
18 |
19 | }
20 |
21 |
22 | public ShadowParam(float radius,float x,float y,String color){
23 | this.radius = radius;
24 | this.x = x;
25 | this.y = y;
26 | this.color = color;
27 | }
28 | }
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/data/StokeParam.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.data;
2 |
3 | import android.graphics.Paint;
4 |
5 | import com.lltvcn.freefont.core.annotation.Description;
6 |
7 | public class StokeParam{
8 |
9 | @Description(name = "描边宽度")
10 | public float width;
11 |
12 | @Description(name = "边角锐度" , cls = Paint.Join.class)
13 | public String join;
14 |
15 | }
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/layer/BaseLayer.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.layer;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Paint;
5 | import android.graphics.RectF;
6 |
7 | import com.lltvcn.freefont.core.animation.ICanvasTransform;
8 |
9 |
10 | /**
11 | * Created by zhaolei on 2017/9/26.
12 | */
13 |
14 | public abstract class BaseLayer implements ILayer{
15 |
16 | protected IPaintHandler paintHandler;
17 | protected IDrawDispatcher drawDispatcher;
18 | protected ICanvasTransform canvasTransform;
19 | private static Paint paint = new Paint();
20 | protected float offsetX,offsetY,degree,scale;
21 | private float absSize;
22 | protected RectF rect;
23 |
24 | @Override
25 | public void setRectF(RectF rect,float absSize) {
26 | this.absSize = absSize;
27 | if(this.rect==null||this.rect!=rect){
28 | this.rect = rect;
29 | onRectChange(rect,absSize);
30 | }
31 | }
32 |
33 | protected void onRectChange(RectF rect,float absSize){
34 |
35 | }
36 |
37 | @Override
38 | public void offset(float x, float y) {
39 | offsetX = x;
40 | offsetY = y;
41 | }
42 |
43 | @Override
44 | public void rotate(float degree) {
45 | this.degree = degree;
46 | }
47 |
48 | @Override
49 | public void scale(float scale) {
50 | this.scale = scale;
51 | }
52 |
53 |
54 | public final void setCanvasTransform(ICanvasTransform canvasTransform) {
55 | this.canvasTransform = canvasTransform;
56 | }
57 |
58 | public final void setPaintHandler(IPaintHandler shader) {
59 | paintHandler = shader;
60 | }
61 |
62 | @Override
63 | public final void draw(int index,Canvas canvas, DrawParam param, Paint paint) {
64 | if(offsetX!=0||offsetY!=0||degree!=0||(scale!=0&&scale!=1)){
65 | canvas.save();
66 | canvas.translate(offsetX*absSize,offsetY*absSize);
67 | if(degree!=0){
68 | canvas.rotate(degree,rect.centerX(),rect.centerY());
69 | }
70 | if(scale!=0&&scale!=1){
71 | canvas.scale(scale,scale,rect.centerX(),rect.centerY());
72 | }
73 | this.paint.reset();
74 | this.paint.set(paint);
75 | if(paintHandler !=null){
76 | paintHandler.handlePaint(index,this.paint,rect);
77 | }
78 | if(canvasTransform !=null){
79 | canvas.save();
80 | canvasTransform.transformCanvas(index,rect,canvas,this.paint);
81 | }
82 | if(drawDispatcher !=null){
83 | drawDispatcher.draw(index,this,canvas,param,this.paint);
84 | }else{
85 | drawLayer(index,canvas,param,this.paint);
86 | }
87 | if(canvasTransform !=null){
88 | canvas.restore();
89 | }
90 | canvas.restore();
91 | }else{
92 | this.paint.reset();
93 | this.paint.set(paint);
94 | if(paintHandler !=null){
95 | paintHandler.handlePaint(index,this.paint,rect);
96 | }
97 | if(canvasTransform !=null){
98 | canvas.save();
99 | canvasTransform.transformCanvas(index,rect,canvas,this.paint);
100 | }
101 | if(drawDispatcher !=null){
102 | drawDispatcher.draw(index,this,canvas,param,this.paint);
103 | }else{
104 | drawLayer(index,canvas,param,this.paint);
105 | }
106 | if(canvasTransform !=null){
107 | canvas.restore();
108 | }
109 | }
110 | }
111 |
112 | public void setDrawDispatcher(IDrawDispatcher dispatcher) {
113 | drawDispatcher = dispatcher;
114 | }
115 |
116 | protected void drawLayer(int index,Canvas c, DrawParam param, Paint paint){
117 |
118 | }
119 |
120 | }
121 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/layer/ClipDrawer.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.layer;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.Canvas;
5 | import android.graphics.Paint;
6 | import android.graphics.Rect;
7 | import android.graphics.RectF;
8 |
9 | /**
10 | * Created by zhaolei on 2017/10/23.
11 | */
12 |
13 | public class ClipDrawer extends DrawDiapatcher{
14 |
15 | private float size;
16 |
17 | public ClipDrawer(float size){
18 | this.size = size;
19 | }
20 |
21 | @Override
22 | protected void drawToCanvas(Bitmap bm, Canvas c, Paint p,RectF aim, Rect from, RectF to) {
23 | float span = p.getTextSize()*size;
24 | c.save();
25 | from.set((int) aim.left,(int) aim.top,(int) aim.right,(int) (aim.top+aim.height()/2));
26 | // from.set(0,0, (int) aim.width(),(int) (aim.height()/2));
27 | to.set(from);
28 | to.offset(0,-span/2);
29 | c.drawBitmap(bm,from,to,null);
30 | from.offset(0, (int) (aim.height()/2));
31 | to.offset(0,aim.height()/2+span);
32 | c.drawBitmap(bm,from,to,null);
33 | c.restore();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/layer/DrawDiapatcher.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.layer;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.Canvas;
5 | import android.graphics.Color;
6 | import android.graphics.Paint;
7 | import android.graphics.PorterDuff;
8 | import android.graphics.PorterDuffXfermode;
9 | import android.graphics.Rect;
10 | import android.graphics.RectF;
11 |
12 | /**
13 | * Created by zhaolei on 2017/10/23.
14 | */
15 |
16 | public abstract class DrawDiapatcher implements ILayer.IDrawDispatcher{
17 |
18 | private static Bitmap bitmap;
19 | private static Canvas canvas;
20 | private static Paint paint = new Paint();
21 | private static RectF toRect = new RectF();
22 | private static Rect fromRect = new Rect();
23 |
24 |
25 |
26 | @Override
27 | public void draw(int index,ILayer layer, Canvas c, ILayer.DrawParam param, Paint p) {
28 | if(layer instanceof BaseLayer){
29 | BaseLayer baseLayer = (BaseLayer) layer;
30 | if(bitmap == null){
31 | bitmap = Bitmap.createBitmap(1080,1920, Bitmap.Config.ARGB_8888);
32 | canvas = new Canvas(bitmap);
33 | }
34 | paint.setColor(Color.TRANSPARENT);
35 | paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
36 | canvas.drawPaint(paint);
37 | baseLayer.drawLayer(index,canvas,param,p);
38 | drawToCanvas(bitmap,c,p,baseLayer.rect,fromRect,toRect);
39 | }
40 | }
41 |
42 | protected void setRect(RectF res ,Rect to){
43 | to.set((int)res.left,(int)res.top,(int)res.right,(int)res.bottom);
44 | }
45 |
46 |
47 | protected abstract void drawToCanvas(Bitmap bm,Canvas c,Paint p,RectF aim,Rect from,RectF to);
48 | }
49 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/layer/FontStyle.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.layer;
2 |
3 | /**
4 | * Created by zhaolei on 2017/10/18.
5 | */
6 |
7 | public enum FontStyle {
8 | Normal,Bold,Italic,Bold_Italic
9 | }
10 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/layer/ILayer.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.layer;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Paint;
5 | import android.graphics.RectF;
6 |
7 | import com.lltvcn.freefont.core.animation.ICanvasTransform;
8 |
9 | /**
10 | * Created by zhaolei on 2017/9/21.
11 | */
12 |
13 | public interface ILayer {
14 |
15 | void draw(int index,Canvas canvas, DrawParam param,Paint paint);
16 |
17 | void setRectF(RectF rect,float absSize);
18 |
19 | void offset(float x,float y);
20 |
21 | void rotate(float degree);
22 |
23 | void scale(float scale);
24 |
25 | void setPaintHandler(IPaintHandler shader);
26 |
27 | void setDrawDispatcher(IDrawDispatcher dispatcher);
28 |
29 | void setCanvasTransform(ICanvasTransform transform);
30 |
31 |
32 |
33 | /**
34 | * layer 可以叠加,offset(x,y),
35 | * txtlayer:mask(blur,emo---),textsize
36 | * imglayer:调整
37 | * 变换:分割,平移分割,波纹......
38 | * 以上中paint 通用的可以设置的属性:shader,mask,shadow,*/
39 |
40 |
41 |
42 | interface IPaintHandler {
43 | void handlePaint(int index,Paint paint,RectF rectF);
44 | }
45 |
46 | interface IDrawDispatcher {
47 | void draw(int index,ILayer layer,Canvas canvas, DrawParam param,Paint paint);
48 | }
49 |
50 | interface DrawParam{
51 |
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/layer/ImgLayer.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.layer;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.Canvas;
5 | import android.graphics.Paint;
6 | import android.graphics.Rect;
7 | import android.graphics.RectF;
8 | import android.graphics.drawable.ColorDrawable;
9 | import android.graphics.drawable.Drawable;
10 |
11 | import com.lltvcn.freefont.core.data.DrawData;
12 | import com.lltvcn.freefont.core.data.IndexParam;
13 | import com.lltvcn.freefont.core.data.LayerData;
14 | import com.lltvcn.freefont.core.util.CU;
15 |
16 | /**
17 | * Created by zhaolei on 2017/9/27.
18 | */
19 |
20 | public class ImgLayer extends BaseLayer{
21 |
22 | private Rect from = new Rect();
23 | private RectF to = new RectF();
24 | private float scaleX,scaleY,curScale;
25 | private DrawableLoader loader;
26 |
27 |
28 | public ImgLayer(DrawableLoader loader){
29 | this.loader = loader;
30 | // this.colors = data.colors;
31 | // this.imgs = data.imgs;
32 | // bitmapSourceLoader = loader;
33 | }
34 |
35 | @Override
36 | protected void drawLayer(int index,Canvas c, DrawParam param, Paint paint) {
37 | if(loader!=null){
38 | Drawable drawable = loader.getDrawable(index);
39 | float scaleX = rect.width()/drawable.getIntrinsicWidth();
40 | float scaleY = rect.height()/drawable.getIntrinsicHeight();
41 |
42 | if(drawable!=null){
43 | drawable.setBounds((int) rect.left,(int) rect.top,(int) rect.right,(int) rect.bottom);
44 | drawable.draw(c);
45 | }
46 | }
47 | // if(bm!=null){
48 | // from.set(0,0,bm.getWidth(),bm.getHeight());
49 | // scaleX = rect.width()/from.width();
50 | // scaleY = rect.height()/from.height();
51 | // curScale = Math.min(scaleX,scaleY);
52 | // to.set(0,0,from.width()*curScale,from.height()*curScale);
53 | // to.offset(rect.centerX()-to.centerX(),rect.centerY()-to.centerY());
54 | // c.drawBitmap(bm,from,to,paint);
55 | // }
56 | }
57 |
58 | public interface DrawableLoader{
59 | Drawable getDrawable(int index);
60 | }
61 |
62 |
63 |
64 |
65 | public static class ImgParam{
66 | public int index;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/layer/LayerSpan.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.layer;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Matrix;
5 | import android.graphics.Paint;
6 | import android.graphics.RectF;
7 | import android.text.style.ReplacementSpan;
8 | import android.util.Log;
9 |
10 |
11 | import com.lltvcn.freefont.core.animation.ICanvasTransform;
12 |
13 | import java.util.ArrayList;
14 |
15 | /**
16 | * Created by zhaolei on 2017/9/21.
17 | */
18 |
19 | public class LayerSpan extends ReplacementSpan{
20 |
21 | private float rH,rW;
22 | private ArrayList layers;
23 | private Matrix matrix = new Matrix();
24 | private Paint.FontMetricsInt fontMetrics = new Paint.FontMetricsInt();
25 | private Paint.FontMetricsInt paintMetrics = new Paint.FontMetricsInt();
26 | private ICanvasTransform canvasTransform;
27 | private static Paint staticPaint = new Paint();
28 |
29 | public LayerSpan(float relativeHeight, float relativeWidth){
30 | rH = relativeHeight;
31 | rW = relativeWidth;
32 | layers = new ArrayList<>();
33 | }
34 |
35 |
36 | public void addLayer(ILayer layer){
37 | layers.add(layer);
38 | }
39 |
40 | public void setCanvasTransform(ICanvasTransform transform){
41 | canvasTransform = transform;
42 | }
43 |
44 |
45 |
46 | @Override
47 | public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
48 | if (fm != null) {
49 | Log.i("txt-getSize-start",fm.toString());
50 | Paint.FontMetricsInt fontMetricsInt = paint.getFontMetricsInt();
51 | fm.ascent = fontMetricsInt.ascent;
52 | fm.descent = fontMetricsInt.descent;
53 | fm.top = fontMetricsInt.top;
54 | fm.bottom = fontMetricsInt.bottom;
55 | if(rH!=1&&rH!=0){
56 | // int moreH = ((int) (paint.getTextSize()*rH)-(fm.bottom-fm.top))/2;
57 | fm.top = (int) (fm.top*rH);
58 | fm.ascent = (int) (fm.ascent*rH);
59 | fm.bottom = (int) (fm.bottom*rH);
60 | fm.descent = (int) (fm.descent*rH);
61 | }
62 | fontMetrics.ascent = fm.ascent;
63 | fontMetrics.descent = fm.descent;
64 | fontMetrics.top = fm.top;
65 | fontMetrics.bottom = fm.bottom;
66 | Log.i("txt-getSize-end",fm.toString()+":::size:"+paint.getTextSize());
67 | }
68 | int width = measureWidth(paint,text,start,end);
69 | Log.i("BaseSpanNew","getSize:"+width);
70 | return width;
71 | }
72 |
73 | @Override
74 | public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
75 | // float scale = S.S /paint.getTextSize();
76 | Log.i("BaseSpanNew","draw");
77 | Log.i("txt-draw-top",""+top+"bottom"+bottom);
78 | Log.i("txt-draw",fontMetrics.toString());
79 | float txtSize = paint.getTextSize();
80 |
81 | RectF rect = new RectF();
82 | int width = measureWidth(paint,text,start,end);
83 | int height = bottom-top;
84 |
85 | rect.set(x,y+fontMetrics.ascent,width+x,y+fontMetrics.descent);
86 |
87 | // rect.set(x,top,width+x,bottom);
88 | // if(scale!=1){
89 | // canvas.save();
90 | // paint.setTextSize(S.S);
91 | //// getSize(paint,text,start,end,paint.getFontMetricsInt());
92 | // float tempY = y-rect.centerY();
93 | // canvas.scale(1f/scale,1f/scale,rect.centerX(),rect.centerY());
94 | // matrix.setScale(scale,scale,rect.centerX(),rect.centerY());
95 | // matrix.mapRect(rect);
96 | //// canvas.scale(scale,scale,rect.centerX(),rect.centerY());
97 | //
98 | //// canvas.setMatrix(matrix);
99 | //// canvas.concat(matrix);
100 | //// canvas.scale(scale,scale,rect.centerX(),rect.centerY());
101 | // Shader shader = paint.getShader();
102 | // if(shader!=null){
103 | // shader.setLocalMatrix(matrix);
104 | // }
105 | // width = (int) (scale*width);
106 | // height = (int) (scale*height);
107 | // Paint.FontMetrics metrics = paint.getFontMetrics();
108 | // y = (int) (rect.centerY()-(metrics.descent+metrics.ascent)/2);
109 | // matrix.reset();
110 | // }
111 | paint.getFontMetricsInt(paintMetrics);
112 | DrawParamI param = new DrawParamI();
113 | param.txtParam.text = text;
114 | if(rW>0){
115 | param.txtParam.x = (width-paint.measureText(text,start,end))/2+rect.left;
116 | }else{
117 | param.txtParam.x = rect.left;
118 | }
119 |
120 | param.txtParam.centerY = rect.centerY();
121 | param.txtParam.y = rect.centerY()-(paintMetrics.descent+paintMetrics.ascent)/2f;
122 | // param.txtParam.y = y;
123 |
124 |
125 |
126 | // if(rH>0&&rH!=1){
127 | // param.txtParam.y = (height-paint.getTextSize())/2+y;
128 | // }else{
129 | // param.txtParam.y = y;
130 | // }
131 | param.txtParam.start = start;
132 | param.txtParam.end = end;
133 | if(canvasTransform!=null){
134 | staticPaint.set(paint);
135 | canvas.save();
136 | canvasTransform.transformCanvas(start,rect,canvas,staticPaint);
137 | for (ILayer layer:layers) {
138 | layer.setRectF(rect,staticPaint.getTextSize());
139 | layer.draw(start,canvas,param,staticPaint);
140 | }
141 | canvas.restore();
142 | }else{
143 | for (ILayer layer:layers) {
144 | layer.setRectF(rect,paint.getTextSize());
145 | layer.draw(start,canvas,param,paint);
146 | }
147 | }
148 | // if(scale!=1){
149 | // canvas.restore();
150 | // paint.setTextSize(txtSize);
151 | // }
152 | }
153 |
154 | private int measureWidth(Paint paint,CharSequence text, int start, int end){
155 | // float scale = paint.getTextScaleX();
156 | // if(rW!=1){
157 | // paint.setTextScaleX(rW);
158 | // }
159 | // int width = (int) paint.measureText(text,start,end);
160 | // paint.setTextScaleX(scale);
161 | // return width;
162 | return rW>0? (int) (rW * paint.getTextSize() * (end - start)): (int) paint.measureText(text, start, end);
163 | }
164 |
165 | private class DrawParamI implements TxtLayer.ITxtDrawParam{
166 | public TxtLayer.TxtParam txtParam = new TxtLayer.TxtParam();
167 |
168 | @Override
169 | public TxtLayer.TxtParam getTxtParam() {
170 | return txtParam;
171 | }
172 |
173 |
174 | }
175 | }
176 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/layer/MultiLayer.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.layer;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Paint;
5 | import android.graphics.RectF;
6 |
7 | import java.util.ArrayList;
8 |
9 | /**
10 | * Created by zhaolei on 2017/10/19.
11 | */
12 |
13 | public class MultiLayer extends BaseLayer{
14 | protected ArrayList layers;
15 | private static Paint multiPaint = new Paint();
16 |
17 | public MultiLayer(ArrayList layers){
18 | this.layers = layers;
19 | }
20 |
21 |
22 | public MultiLayer(){
23 | }
24 |
25 |
26 | @Override
27 | protected void onRectChange(RectF rect, float absSize) {
28 | if(layers!=null){
29 | for (ILayer layer:layers) {
30 | layer.setRectF(rect,absSize);
31 | }
32 | }
33 | }
34 |
35 | public final void add(ILayer layer) {
36 | if(layers == null){
37 | layers = new ArrayList<>(1);
38 | }
39 | layers.add(layer);
40 | }
41 |
42 | public final void remove(ILayer layer) {
43 | layers.remove(layer);
44 | }
45 |
46 | @Override
47 | protected void drawLayer(int index,Canvas c, DrawParam param, Paint paint) {
48 | multiPaint.reset();
49 | multiPaint.set(paint);
50 | if(layers!=null){
51 | for (ILayer layer:layers) {
52 | layer.draw(index,c,param,multiPaint);
53 | }
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/layer/OffsetDrawer.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.layer;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.Canvas;
5 | import android.graphics.Paint;
6 | import android.graphics.Rect;
7 | import android.graphics.RectF;
8 |
9 | /**
10 | * Created by zhaolei on 2017/10/23.
11 | */
12 |
13 | public class OffsetDrawer extends DrawDiapatcher{
14 | private float[] positions,offsets;
15 |
16 | public OffsetDrawer(float[] positions,float[] offsets){
17 | this.positions = positions;
18 | this.offsets = offsets;
19 | }
20 |
21 | @Override
22 | protected void drawToCanvas(Bitmap bm, Canvas c, Paint p, RectF aim, Rect from, RectF to) {
23 | if(positions!=null){
24 | int offsetY = 0;
25 | for (int i = 0; i < positions.length; i++) {
26 | from.set((int) aim.left,(int)aim.top+offsetY,(int)aim.right,(int)aim.top+(offsetY+=aim.height()*positions[i]));
27 | if(offsetY>aim.bottom){
28 | return;
29 | }
30 | to.set(from);
31 | to.offset(offsets[i]*p.getTextSize(),0);
32 | c.drawBitmap(bm,from,to,null);
33 | }
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/layer/PaintHandler.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.layer;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.BitmapShader;
5 | import android.graphics.BlurMaskFilter;
6 | import android.graphics.Color;
7 | import android.graphics.LinearGradient;
8 | import android.graphics.Matrix;
9 | import android.graphics.Paint;
10 | import android.graphics.RadialGradient;
11 | import android.graphics.RectF;
12 | import android.graphics.Shader;
13 | import android.graphics.SweepGradient;
14 | import android.graphics.Typeface;
15 | import android.text.TextUtils;
16 | import android.util.Log;
17 |
18 | import com.lltvcn.freefont.core.data.LayerData;
19 | import com.lltvcn.freefont.core.data.ShaderBitmapParam;
20 | import com.lltvcn.freefont.core.data.ShaderParam;
21 | import com.lltvcn.freefont.core.util.CU;
22 |
23 |
24 | /**
25 | * Created by zhaolei on 2017/10/11.
26 | */
27 |
28 | public class PaintHandler implements ILayer.IPaintHandler {
29 |
30 | public static final float S = 300;
31 | public static final RectF R = new RectF(0,0,S,S);
32 | private LayerData.PaintParam paintParam;
33 | private BlurMaskFilter maskFilter;
34 | private Shader shader;
35 | private Matrix matrix;
36 | private SourceLoader loader;
37 | private SourceLoader fontLoader;
38 | private RectF shadeRect;
39 |
40 | public PaintHandler(LayerData.PaintParam param){
41 | this(param,null,null);
42 | }
43 |
44 | public PaintHandler(LayerData.PaintParam param, SourceLoader loader, SourceLoader fontLoader){
45 | paintParam = param;
46 | this.loader = loader;
47 | this.fontLoader = fontLoader;
48 | if(paintParam!=null){
49 | if(paintParam.blurParam!=null){
50 | maskFilter = new BlurMaskFilter(param.blurParam.radius* S, BlurMaskFilter.Blur.valueOf(param.blurParam.blur));
51 | }
52 | if(paintParam.shaderParam!=null){
53 | shader = generalShaderByParam(paintParam.shaderParam);
54 | }
55 | if(shader!=null){
56 | matrix = new Matrix();
57 | }
58 | }
59 | }
60 |
61 | @Override
62 | public void handlePaint(int index,Paint paint, RectF rectF) {
63 | float textSize = paint.getTextSize();
64 | float alpha = paint.getAlpha()/255f;
65 | if(!TextUtils.isEmpty(paintParam.color)){
66 | paint.setColor(CU.toInt(paintParam.color));
67 | }else if(paintParam.colors!=null&&paintParam.colors.available()){
68 | paint.setColor(CU.toInt(paintParam.colors.getDataByIndex(index)));
69 | }
70 | paint.setAlpha((int) (alpha*paint.getAlpha()));
71 | if(!TextUtils.isEmpty(paintParam.style)){
72 | paint.setStyle(Paint.Style.valueOf(paintParam.style));
73 | }
74 | if(paintParam.stokeParam!=null){
75 | if(alpha>0){
76 | paint.setStyle(Paint.Style.STROKE);
77 | paint.setStrokeWidth(paintParam.stokeParam.width*textSize);
78 | paint.setStrokeJoin(Paint.Join.valueOf(paintParam.stokeParam.join));
79 | }else{
80 | paint.setStrokeWidth(0);
81 | }
82 | }
83 | if(paintParam.relativeSize!=null){
84 | paint.setTextSize(paintParam.relativeSize*textSize);
85 | }
86 | if(!TextUtils.isEmpty(paintParam.font)){
87 | paint.setTypeface(fontLoader.loadByName(paintParam.font));
88 | }
89 | if(!TextUtils.isEmpty(paintParam.fontStyle)){
90 | paint.setTypeface(Typeface.create(paint.getTypeface(),FontStyle.valueOf(paintParam.fontStyle).ordinal()));
91 | }
92 | if(paintParam.shadowParam!=null){
93 | paint.setShadowLayer(paintParam.shadowParam.radius*textSize,paintParam.shadowParam.x*textSize,paintParam.shadowParam.y*textSize, CU.toInt(paintParam.shadowParam.color));
94 | }
95 | if(maskFilter!=null){
96 | paint.setMaskFilter(maskFilter);
97 | }
98 | if(shader!=null){
99 | matrix.reset();
100 | Log.i("jjjjkkk","handlePaint");
101 | matrix.setRectToRect(shadeRect,rectF, Matrix.ScaleToFit.FILL);
102 | // matrix.setTranslate(rectF.left,rectF.top);
103 | shader.setLocalMatrix(matrix);
104 | paint.setShader(shader);
105 | }
106 | }
107 |
108 | private Shader generalShaderByParam(ShaderParam param){
109 | Shader shader = null;
110 | if(param.bitmapParam!=null){
111 | if(loader!=null){
112 | ShaderBitmapParam bitmapParam = param.bitmapParam;
113 | Bitmap bm = loader.loadByName(bitmapParam.img);
114 | if(bm!=null){
115 | // Bitmap tBm = Bitmap.createBitmap((int) S,(int) S, Bitmap.Config.ARGB_8888);
116 | // Canvas canvas = new Canvas(tBm);
117 | // Rect rect = new Rect();
118 | // float scale = 0;
119 | // if(bm.getWidth()>bm.getHeight()){
120 | // int offset = (bm.getWidth()-bm.getHeight())/2;
121 | // rect.set(offset,0,bm.getWidth()-offset,bm.getHeight());
122 | // }else{
123 | // int offset = (bm.getHeight()-bm.getWidth())/2;
124 | // rect.set(0,offset,bm.getWidth(),bm.getHeight()-offset);
125 | // }
126 | // canvas.drawBitmap(bm,rect,S.R,null);
127 | shadeRect = new RectF(0,0,bm.getWidth(),bm.getHeight());
128 | shader = new BitmapShader(bm, Shader.TileMode.valueOf(bitmapParam.tileModeX), Shader.TileMode.valueOf(bitmapParam.tileModeY));
129 | }
130 | }
131 | }
132 | if(param.sweepParam!=null){
133 | // TODO: 2017/10/12 这里没有考虑字的宽度来调整圆心位置
134 | if(param.sweepParam.colors==null||param.sweepParam.colors.length<2){
135 | throw new RuntimeException("LinearGradient param wrong!");
136 | }
137 | if((param.sweepParam.positions==null||param.sweepParam.positions.length==0)&¶m.sweepParam.colors.length==2){
138 | shader = new SweepGradient(param.sweepParam.centerX*S,param.sweepParam.centerY*S,CU.toInt(param.sweepParam.colors[0]),CU.toInt(param.sweepParam.colors[1]));
139 | }else{
140 | shader = new SweepGradient(param.sweepParam.centerX*S,param.sweepParam.centerY*S,CU.toInt(param.sweepParam.colors),param.sweepParam.positions);
141 | }
142 | shadeRect = R;
143 | }
144 | if(param.linearParam!=null){
145 | if(param.linearParam.colors==null||param.linearParam.colors.length<2){
146 | throw new RuntimeException("LinearGradient param wrong!");
147 | }
148 | if((param.linearParam.positions==null||param.linearParam.positions.length==0)&¶m.linearParam.colors.length==2){
149 | shader = new LinearGradient(param.linearParam.x0*S,param.linearParam.y0*S,param.linearParam.x1*S,param.linearParam.y1*S,CU.toInt(param.linearParam.colors[0]),CU.toInt(param.linearParam.colors[1]), Shader.TileMode.valueOf(param.linearParam.tileMode));
150 | }else{
151 | shader = new LinearGradient(param.linearParam.x0*S,param.linearParam.y0*S,param.linearParam.x1*S,param.linearParam.y1*S,
152 | CU.toInt(param.linearParam.colors),param.linearParam.positions, Shader.TileMode.valueOf(param.linearParam.tileMode));
153 | }
154 | shadeRect = R;
155 | }
156 | if(param.radiusParam!=null){
157 | // TODO: 2017/10/12 这里没有考虑字的宽度来调整圆心位置
158 | if(param.radiusParam.colors==null||param.radiusParam.colors.length<2){
159 | throw new RuntimeException("LinearGradient param wrong!");
160 | }
161 | if((param.radiusParam.positions==null||param.radiusParam.positions.length==0)&¶m.radiusParam.colors.length==2){
162 | shader = new RadialGradient(param.radiusParam.centerX*S,param.radiusParam.centerY*S,param.radiusParam.radius*S,CU.toInt(param.radiusParam.colors[0]),CU.toInt(param.radiusParam.colors[1]), Shader.TileMode.valueOf(param.radiusParam.tileMode));
163 | }else{
164 | shader = new RadialGradient(param.radiusParam.centerX*S,param.radiusParam.centerY*S,param.radiusParam.radius*S,CU.toInt(param.radiusParam.colors),param.radiusParam.positions, Shader.TileMode.valueOf(param.radiusParam.tileMode));
165 | }
166 | shadeRect = R;
167 | }
168 | return shader;
169 | }
170 |
171 | }
172 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/layer/SingleWarpSpan.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.layer;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Paint;
5 | import android.text.style.ReplacementSpan;
6 |
7 | /**
8 | * Created by zhaolei on 2017/10/21.
9 | */
10 |
11 | public class SingleWarpSpan extends ReplacementSpan{
12 |
13 | private ReplacementSpan span;
14 |
15 | public SingleWarpSpan(ReplacementSpan span){
16 | this.span = span;
17 | }
18 |
19 |
20 |
21 | @Override
22 | public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
23 | return span.getSize(paint,text,start,end,fm);
24 | }
25 |
26 | @Override
27 | public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
28 | span.draw(canvas,text,start,end,x,top,y,bottom,paint);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/layer/SourceLoader.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.layer;
2 |
3 | public interface SourceLoader {
4 |
5 | T loadByName(String name);
6 |
7 | }
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/layer/TxtLayer.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.layer;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Paint;
5 | import android.util.Log;
6 |
7 |
8 | /**
9 | * Created by zhaolei on 2017/9/26.
10 | */
11 |
12 | public class TxtLayer extends BaseLayer{
13 |
14 |
15 | @Override
16 | public void drawLayer(int index,Canvas canvas, DrawParam param, Paint paint) {
17 | if(param instanceof ITxtDrawParam){
18 | TxtParam txtParam = ((ITxtDrawParam)param).getTxtParam();
19 | if(txtParam!=null){
20 | Paint.FontMetrics metrics = paint.getFontMetrics();
21 | Log.i("draw-txt",""+txtParam.y);
22 | canvas.drawText(txtParam.text,txtParam.start,txtParam.end,txtParam.x,txtParam.y,paint);
23 | // canvas.drawText(txtParam.text,txtParam.start,txtParam.end,txtParam.x,txtParam.centerY-(metrics.bottom+metrics.top)/2f,paint);
24 | }
25 | }
26 | }
27 |
28 | public interface ITxtDrawParam extends DrawParam{
29 | TxtParam getTxtParam();
30 | }
31 |
32 | public static class TxtParam{
33 | public float x,y,centerY;
34 | public int start,end;
35 | public CharSequence text;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/linedrawer/BackgroundDrawer.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.linedrawer;
2 |
3 | /**
4 | * Created by zhaolei on 2017/9/18.
5 | */
6 |
7 | public interface BackgroundDrawer extends LineDrawer{
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/linedrawer/ForegroundDrawer.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.linedrawer;
2 |
3 | /**
4 | * Created by zhaolei on 2017/9/18.
5 | */
6 |
7 | public interface ForegroundDrawer extends LineDrawer{
8 | }
9 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/linedrawer/Gravity.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.linedrawer;
2 |
3 | /**
4 | * Created by zhaolei on 2017/10/17.
5 | */
6 |
7 | public enum Gravity {
8 | CENTER,INNER_TOP,OUT_TOP,INNER_BOTTOM,OUT_BOTTOM
9 | }
10 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/linedrawer/LineDrawer.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.linedrawer;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Paint;
5 |
6 | /**
7 | * Created by zhaolei on 2017/9/18.
8 | */
9 |
10 | public interface LineDrawer{
11 |
12 | void draw(Canvas c, Paint p,float left,int top,float right,int bottom,int baseLine);
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/linedrawer/LineImgBackgroundDrawer.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.linedrawer;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.drawable.BitmapDrawable;
5 | import android.graphics.drawable.Drawable;
6 |
7 | /**
8 | * Created by zhaolei on 2017/9/20.
9 | */
10 |
11 | public class LineImgBackgroundDrawer extends LineImgDrawer implements BackgroundDrawer{
12 |
13 |
14 | public LineImgBackgroundDrawer(Bitmap bm, float relativeHeight, Gravity gravity) {
15 | super(new BitmapDrawable(bm), relativeHeight, gravity);
16 | }
17 |
18 | public LineImgBackgroundDrawer(Drawable drawable, float relativeHeight, Gravity gravity) {
19 | super(drawable, relativeHeight, gravity);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/linedrawer/LineImgDrawer.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.linedrawer;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Matrix;
5 | import android.graphics.Paint;
6 | import android.graphics.Rect;
7 | import android.graphics.drawable.BitmapDrawable;
8 | import android.graphics.drawable.Drawable;
9 | import android.text.Spanned;
10 | import android.text.TextPaint;
11 | import android.text.style.LineHeightSpan;
12 | import android.util.Log;
13 |
14 |
15 | /**
16 | * Created by zhaolei on 2017/9/20.
17 | */
18 |
19 | public class LineImgDrawer implements LineHeightSpan.WithDensity,LineDrawer{
20 |
21 | private Drawable drawable;
22 | private int aimHeight;
23 | private int aimOffset;
24 | private Paint.FontMetricsInt fontMetricsInt = new Paint.FontMetricsInt();
25 | private Gravity gravity;
26 | private float relativeDrawableHeight;
27 | private int startPos = -1;
28 | private int endPos;
29 | private float offset = -0.1f;
30 |
31 | public LineImgDrawer(Drawable drawable, float relativeHeight, Gravity gravity){
32 | this.drawable = drawable;
33 | relativeDrawableHeight = relativeHeight;
34 | this.gravity = gravity;
35 | }
36 |
37 | @Override
38 | public void chooseHeight(CharSequence text, int start, int end, int spanstartv, int v, Paint.FontMetricsInt fm, TextPaint paint) {
39 | if(startPos==-1){
40 | startPos = ((Spanned)text).getSpanStart(this);
41 | endPos = ((Spanned)text).getSpanEnd(this);
42 | }
43 | Log.i("line","start:"+startPos+"end:"+endPos+"ssss"+start+"eeee"+end);
44 | if(endPos=end){
45 | return;
46 | }
47 | updateFM(fm, (int) paint.getTextSize());
48 | }
49 |
50 |
51 | private void updateFM(Paint.FontMetricsInt fm,int txtHeight){
52 | Log.i("line----start",fm.toString());
53 | aimHeight = (int) (relativeDrawableHeight*txtHeight);
54 | aimOffset = (int) (relativeDrawableHeight*txtHeight);
55 | switch (gravity){
56 | case CENTER:
57 | if(aimHeight > txtHeight){
58 | int plus = (aimHeight-txtHeight)/2;
59 | fm.top -= plus;
60 | fm.ascent -= plus;
61 | fm.bottom += plus;
62 | fm.descent += plus;
63 | }
64 | break;
65 | case OUT_TOP:
66 | fm.top -= aimHeight;
67 | fm.ascent -= aimHeight;
68 | break;
69 | case OUT_BOTTOM:
70 | fm.bottom += aimHeight;
71 | fm.descent += aimHeight;
72 | break;
73 | case INNER_TOP:
74 | if (aimHeight>txtHeight) {
75 | int plus = (aimHeight-txtHeight);
76 | fm.bottom += plus;
77 | fm.descent += plus;
78 | }
79 | break;
80 | case INNER_BOTTOM:
81 | if (aimHeight > txtHeight) {
82 | int plus = aimHeight-txtHeight;
83 | fm.top -= plus;
84 | fm.ascent -= plus;
85 | }
86 | break;
87 | }
88 | fontMetricsInt.top = fm.top;
89 | fontMetricsInt.ascent = fm.ascent;
90 | fontMetricsInt.bottom = fm.bottom;
91 | fontMetricsInt.descent = fm.descent;
92 | Log.i("line---end",fm.toString());
93 | }
94 |
95 | @Override
96 | public void chooseHeight(CharSequence text, int start, int end, int spanstartv, int v, Paint.FontMetricsInt fm) {
97 |
98 | }
99 |
100 | @Override
101 | public void draw(Canvas c, Paint p, float left, int top, float right, int bottom , int baseLine) {
102 | Log.i("line-draw","top:"+top+"bottom:"+bottom);
103 | top = baseLine+fontMetricsInt.ascent;
104 | bottom = baseLine+fontMetricsInt.descent;
105 | switch (gravity){
106 | case CENTER:
107 | int moreH = bottom-top-aimHeight;
108 | top+=moreH/2;
109 | bottom-=moreH/2;
110 | break;
111 | case INNER_TOP:
112 | case OUT_TOP:
113 | bottom = top+aimHeight;
114 | break;
115 | case INNER_BOTTOM:
116 | case OUT_BOTTOM:
117 | top = bottom-aimHeight;
118 | break;
119 | }
120 |
121 | if(drawable instanceof BitmapDrawable){
122 | float dstHeight = bottom-top;
123 | float scale = dstHeight/drawable.getIntrinsicHeight();
124 | int width = (int) (drawable.getIntrinsicWidth()*scale);
125 |
126 | int leftIndex = (int) left;
127 | while (leftIndexright){
129 | c.save();
130 | c.clipRect(leftIndex,top,right,bottom);
131 | drawable.setBounds(leftIndex,top,leftIndex+width,bottom);
132 | drawable.draw(c);
133 | c.restore();
134 | }else {
135 | drawable.setBounds(leftIndex,top,leftIndex+width,bottom);
136 | drawable.draw(c);
137 | }
138 | leftIndex+=width;
139 | }
140 | }else{
141 | drawable.setBounds((int)left,top,(int)right,bottom);
142 | drawable.draw(c);
143 | }
144 | }
145 |
146 | }
147 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/linedrawer/LineImgForegroundDrawer.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.linedrawer;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.drawable.BitmapDrawable;
5 | import android.graphics.drawable.Drawable;
6 |
7 | /**
8 | * Created by zhaolei on 2017/9/20.
9 | */
10 |
11 | public class LineImgForegroundDrawer extends LineImgDrawer implements ForegroundDrawer{
12 |
13 |
14 | public LineImgForegroundDrawer(Bitmap bm, float relativeHeight, Gravity gravity) {
15 | super(new BitmapDrawable(bm), relativeHeight, gravity);
16 | }
17 |
18 | public LineImgForegroundDrawer(Drawable drawable, float relativeHeight, Gravity gravity) {
19 | super(drawable, relativeHeight, gravity);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/util/CU.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.util;
2 |
3 | import android.graphics.Color;
4 | import android.graphics.PorterDuff;
5 | import android.graphics.PorterDuffColorFilter;
6 | import android.graphics.drawable.Drawable;
7 |
8 | /**
9 | * Created by zhaolei on 2017/10/21.
10 | */
11 |
12 | public class CU {
13 |
14 | public static int toInt(String color){
15 | if(color.startsWith("#")){
16 | return Color.parseColor(color);
17 | }else{
18 | return Color.parseColor("#"+color);
19 | }
20 | }
21 |
22 | public static int[] toInt(String[] colors){
23 | int[] result = new int[colors.length];
24 | for (int i = 0; i < result.length; i++) {
25 | result[i] = toInt(colors[i]);
26 | }
27 | return result;
28 | }
29 |
30 | public static String toString(int color){
31 | return Integer.toHexString(color);
32 | }
33 |
34 | public static void filterDrawable(Drawable drawable,int color){
35 | if(drawable==null) return;
36 | drawable.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
37 | }
38 |
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/view/ShadeEditText.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.view;
2 |
3 | import android.content.Context;
4 | import android.graphics.Canvas;
5 | import android.text.Layout;
6 | import android.text.SpannableStringBuilder;
7 | import android.text.Spanned;
8 | import android.text.StaticLayout;
9 | import android.util.AttributeSet;
10 | import android.util.Log;
11 | import android.widget.EditText;
12 |
13 | import com.lltvcn.freefont.core.layer.LayerSpan;
14 | import com.lltvcn.freefont.core.layer.SingleWarpSpan;
15 | import com.lltvcn.freefont.core.linedrawer.BackgroundDrawer;
16 | import com.lltvcn.freefont.core.linedrawer.ForegroundDrawer;
17 | import com.lltvcn.freefont.core.linedrawer.LineDrawer;
18 |
19 | /**
20 | * Created by zhaolei on 2017/10/12.
21 | */
22 |
23 | public class ShadeEditText extends EditText{
24 | private SpannableStringBuilder sb;
25 |
26 |
27 | public ShadeEditText(Context context, AttributeSet attrs) {
28 | super(context, attrs);
29 | }
30 |
31 | @Override
32 | public void setText(CharSequence text, BufferType type) {
33 | Log.i("jjjjjjjj","setText"+text);
34 | if(text instanceof SpannableStringBuilder){
35 | sb = (SpannableStringBuilder) text;
36 | LayerSpan[] spans = sb.getSpans(0,sb.length(),LayerSpan.class);
37 | if(spans!=null){
38 | for (int i = 0; i < sb.length(); i++) {
39 | spans = sb.getSpans(i,i+1,LayerSpan.class);
40 | if(spans!=null&&spans.length>0){
41 | sb.setSpan(new SingleWarpSpan(spans[spans.length-1]),i,i+1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
42 | }
43 | }
44 | }
45 | remove(sb,LayerSpan.class);
46 | }else{
47 | sb = null;
48 | }
49 | super.setText(text, type);
50 | }
51 |
52 | private void remove(SpannableStringBuilder sb,Class c){
53 | T[] spans = sb.getSpans(0,sb.length(), c);
54 | if(spans!=null){
55 | for (int i = 0; i < spans.length; i++) {
56 | sb.removeSpan(spans[i]);
57 | }
58 | }
59 | }
60 |
61 | @Override
62 | protected void onDraw(Canvas canvas) {
63 | if (getLayout() != null && sb != null) {
64 | drawLineRect(canvas,getLayout(),BackgroundDrawer.class);
65 | super.onDraw(canvas);
66 | drawLineRect(canvas,getLayout(),ForegroundDrawer.class);
67 | } else {
68 | super.onDraw(canvas);
69 | }
70 | }
71 |
72 | private void drawLineRect(Canvas canvas, Layout layout, Class drawerClass) {
73 | LineDrawer[] drawers = sb.getSpans(0, sb.length(), drawerClass);
74 | if (drawers != null) {
75 | LineDrawer drawer = null;
76 | int lineStart,lineEnd,spanStar,spanEnd;
77 | float left,right;
78 | int lineCount = getLineCount();
79 | for (int line = 0; line < lineCount; line++) {
80 | lineStart = layout.getLineStart(line);
81 | lineEnd = layout.getLineEnd(line);
82 | for (int j = 0; j < drawers.length; j++) {
83 | drawer = drawers[j];
84 | spanStar = Math.max(lineStart,sb.getSpanStart(drawer));
85 | spanEnd = Math.min(lineEnd,sb.getSpanEnd(drawer));
86 | if(spanEnd>spanStar){
87 | if(lineStartspanEnd){
93 | right = layout.getLineRight(line)- StaticLayout.getDesiredWidth(sb,spanEnd,lineEnd,getPaint());
94 | }else {
95 | right = layout.getLineRight(line);
96 | }
97 | left+=getPaddingLeft();
98 | right+=getPaddingLeft();
99 |
100 | drawer.draw(canvas,getPaint(),left,layout.getLineTop(line)+getPaddingTop(), right ,layout.getLineBottom(line)+getPaddingTop(),layout.getLineBaseline(line));
101 | }
102 | }
103 | }
104 | }
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/freefont/src/main/java/com/lltvcn/freefont/core/view/ShadeTextView.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont.core.view;
2 |
3 | import android.content.Context;
4 | import android.graphics.Canvas;
5 | import android.graphics.Paint;
6 | import android.text.Layout;
7 | import android.text.SpannableStringBuilder;
8 | import android.text.Spanned;
9 | import android.text.StaticLayout;
10 | import android.text.style.RelativeSizeSpan;
11 | import android.util.AttributeSet;
12 | import android.widget.TextView;
13 |
14 | import com.lltvcn.freefont.core.layer.LayerSpan;
15 | import com.lltvcn.freefont.core.layer.SingleWarpSpan;
16 | import com.lltvcn.freefont.core.linedrawer.BackgroundDrawer;
17 | import com.lltvcn.freefont.core.linedrawer.ForegroundDrawer;
18 | import com.lltvcn.freefont.core.linedrawer.LineDrawer;
19 |
20 |
21 | /**
22 | * Created by zhaolei on 2017/9/18.
23 | */
24 |
25 | public class ShadeTextView extends TextView{
26 | private SpannableStringBuilder sb;
27 |
28 | public ShadeTextView(Context context) {
29 | this(context, null);
30 | }
31 |
32 |
33 | public ShadeTextView(Context context, AttributeSet attrs) {
34 | super(context, attrs);
35 | }
36 |
37 |
38 |
39 |
40 | @Override
41 | public void setText(CharSequence text, BufferType type) {
42 | if(text instanceof SpannableStringBuilder){
43 | // sb = (SpannableStringBuilder) text;
44 | // for (int i = 0; i < sb.length(); i++) {
45 | // sb.setSpan(new RelativeSizeSpan(1.0f),i,i+1,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
46 | // }
47 | sb = (SpannableStringBuilder) text;
48 | LayerSpan[] spans = sb.getSpans(0,sb.length(),LayerSpan.class);
49 | if(spans!=null){
50 | for (int i = 0; i < sb.length(); i++) {
51 | spans = sb.getSpans(i,i+1,LayerSpan.class);
52 | if(spans!=null&&spans.length>0){
53 | sb.setSpan(new SingleWarpSpan(spans[spans.length-1]),i,i+1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
54 | }
55 | }
56 | }
57 | remove(sb,LayerSpan.class);
58 | }else{
59 | sb = null;
60 | }
61 | super.setText(text, type);
62 | // if(sb!=null){
63 | // remove(sb,LeadingMarginSpan.class);
64 | // remove(sb, LeadingMarginSpan.LeadingMarginSpan2.class);
65 | // }
66 | }
67 |
68 | private void remove(SpannableStringBuilder sb,Class c){
69 | T[] spans = sb.getSpans(0,sb.length(), c);
70 | if(spans!=null){
71 | for (int i = 0; i < spans.length; i++) {
72 | sb.removeSpan(spans[i]);
73 | }
74 | }
75 | }
76 |
77 | @Override
78 | protected void onDraw(Canvas canvas) {
79 | if (getLayout() != null && sb != null) {
80 | Paint.FontMetricsInt fontMetricsInt = new Paint.FontMetricsInt();
81 | getPaint().getFontMetricsInt(fontMetricsInt);
82 | drawLineRect(fontMetricsInt,canvas,getLayout(),BackgroundDrawer.class);
83 | super.onDraw(canvas);
84 | drawLineRect(fontMetricsInt,canvas,getLayout(),ForegroundDrawer.class);
85 | } else {
86 | super.onDraw(canvas);
87 | }
88 | }
89 |
90 | private void drawLineRect(Paint.FontMetricsInt fontMetricsInt,Canvas canvas, Layout layout, Class drawerClass) {
91 | LineDrawer[] drawers = sb.getSpans(0, sb.length(), drawerClass);
92 | if (drawers != null) {
93 | LineDrawer drawer = null;
94 | int lineStart,lineEnd,spanStar,spanEnd;
95 | float left,right;
96 | int lineCount = getLineCount();
97 | for (int line = 0; line < lineCount; line++) {
98 | lineStart = layout.getLineStart(line);
99 | lineEnd = layout.getLineEnd(line);
100 | for (int j = 0; j < drawers.length; j++) {
101 | drawer = drawers[j];
102 | spanStar = Math.max(lineStart,sb.getSpanStart(drawer));
103 | spanEnd = Math.min(lineEnd,sb.getSpanEnd(drawer));
104 | if(spanEnd>spanStar){
105 | if(lineStartspanEnd){
111 | right = layout.getLineRight(line)-StaticLayout.getDesiredWidth(sb,spanEnd,lineEnd,getPaint());
112 | }else {
113 | right = layout.getLineRight(line);
114 | }
115 | left+=getPaddingLeft();
116 | right+=getPaddingLeft();
117 | // drawer.draw(canvas,getPaint(),left,layout.getLineBaseline(line)+fontMetricsInt.top+getPaddingTop(), right ,layout.getLineBaseline(line)+fontMetricsInt.bottom+getPaddingTop());
118 |
119 | drawer.draw(canvas,getPaint(),left,layout.getLineTop(line)+getPaddingTop(), right ,layout.getLineBottom(line)+getPaddingTop(),layout.getLineBaseline(line));
120 | }
121 | }
122 | }
123 | }
124 | }
125 |
126 | }
127 |
--------------------------------------------------------------------------------
/freefont/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | FreeFont
3 |
4 |
--------------------------------------------------------------------------------
/freefont/src/test/java/com/lltvcn/freefont/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.lltvcn.freefont;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lltvcn/FreeText/d8d6daa5bb6872017e04b7f72f3e54b239a16798/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Dec 28 10:00:20 PST 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/res/res.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lltvcn/FreeText/d8d6daa5bb6872017e04b7f72f3e54b239a16798/res/res.gif
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':freefont'
2 |
--------------------------------------------------------------------------------