diff --git a/build.gradle b/build.gradle
index e4da491..c01f2f8 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,14 +5,19 @@ buildscript {
google()
mavenCentral()
jcenter()
+ maven { url "https://jitpack.io" }
}
dependencies {
classpath "com.android.tools.build:gradle:4.1.1"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
-
+ classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
+ classpath 'com.github.LukeXeon.android-iconfont-pipeline:iconfont-assets:ab8517244c'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
+ ext {
+ groupId = 'com.github.LukeXeon'
+ }
}
allprojects {
@@ -20,9 +25,12 @@ allprojects {
google()
mavenCentral()
jcenter()
+ maven { url "https://jitpack.io" }
}
}
task clean(type: Delete) {
delete rootProject.buildDir
-}
\ No newline at end of file
+}
+
+
diff --git a/iconfont-app/build.gradle b/iconfont-app/build.gradle
index 67f211d..bcce260 100644
--- a/iconfont-app/build.gradle
+++ b/iconfont-app/build.gradle
@@ -1,6 +1,10 @@
-plugins {
- id 'com.android.application'
- id 'kotlin-android'
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+apply plugin: 'open.source.iconfont.assets'
+
+iconfont {
+ host = 'https://icon-font-assets.oss-cn-beijing.aliyuncs.com'
+ version = '0.0.1'
}
android {
diff --git a/iconfont-app/src/main/res/layout/activity_main.xml b/iconfont-app/src/main/res/layout/activity_main.xml
index 7ee16c1..49837f5 100644
--- a/iconfont-app/src/main/res/layout/activity_main.xml
+++ b/iconfont-app/src/main/res/layout/activity_main.xml
@@ -2,19 +2,15 @@
+
-
-
+ app:srcCompat="@drawable/ref_daka_11" />
\ No newline at end of file
diff --git a/iconfont-assets/build.gradle b/iconfont-assets/build.gradle
index e3250f0..186a88e 100644
--- a/iconfont-assets/build.gradle
+++ b/iconfont-assets/build.gradle
@@ -1,8 +1,9 @@
apply plugin: 'java-gradle-plugin'
apply plugin: 'groovy'
apply plugin: 'maven'
-version = '1.0.0'
-group = 'open.source.iconfont'
+apply plugin: 'maven-publish'
+
+group = rootProject.ext.groupId
java {
sourceCompatibility = JavaVersion.VERSION_1_7
@@ -14,3 +15,19 @@ dependencies {
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
}
+
+afterEvaluate {
+ publishing {
+ publications {
+ // Creates a Maven publication called "release".
+ release(MavenPublication) {
+ from components.java
+ groupId = rootProject.ext.groupId
+ artifactId = 'iconfont-assets'
+ }
+ }
+ repositories {
+ mavenLocal()
+ }
+ }
+}
\ No newline at end of file
diff --git a/iconfont-assets/src/main/java/open/source/iconfont/assets/GenAssetsPlugin.groovy b/iconfont-assets/src/main/groovy/open/source/iconfont/assets/GenAssetsPlugin.groovy
similarity index 100%
rename from iconfont-assets/src/main/java/open/source/iconfont/assets/GenAssetsPlugin.groovy
rename to iconfont-assets/src/main/groovy/open/source/iconfont/assets/GenAssetsPlugin.groovy
diff --git a/iconfont-assets/src/main/java/open/source/iconfont/assets/GenAssetsTask.groovy b/iconfont-assets/src/main/groovy/open/source/iconfont/assets/GenAssetsTask.groovy
similarity index 85%
rename from iconfont-assets/src/main/java/open/source/iconfont/assets/GenAssetsTask.groovy
rename to iconfont-assets/src/main/groovy/open/source/iconfont/assets/GenAssetsTask.groovy
index 822ab65..e20adcd 100644
--- a/iconfont-assets/src/main/java/open/source/iconfont/assets/GenAssetsTask.groovy
+++ b/iconfont-assets/src/main/groovy/open/source/iconfont/assets/GenAssetsTask.groovy
@@ -12,13 +12,12 @@ import retrofit2.converter.gson.GsonConverterFactory
import java.nio.file.Paths
import java.util.concurrent.Callable
+import java.util.function.Function
class GenAssetsTask extends DefaultTask {
private final Gson gson
- private static final int RETRY_TIME = 10
-
GenAssetsTask() {
gson = new Gson()
}
@@ -62,21 +61,15 @@ class GenAssetsTask extends DefaultTask {
))
}
- private T fetch(Callable callable) {
- int count = 0
- def result
- while (true) {
- if (++count > RETRY_TIME) {
- throw new IllegalStateException(project.extensions.iconfont.host + "出问题了,或者version不对")
- }
- try {
- result = callable.call()
- } catch (Throwable ignored) {
- continue
- }
- if (result != null) {
- break
+ private static T fetch(Callable callable, Function factory) {
+ def result = null
+ try {
+ result = callable.call()
+ if (result == null) {
+ throw new NullPointerException()
}
+ } catch (Throwable e) {
+ throw factory.apply(e)
}
return result
}
@@ -121,6 +114,11 @@ class GenAssetsTask extends DefaultTask {
}
return null
}
+ }, new Function() {
+ @Override
+ Throwable apply(Throwable throwable) {
+ return new IllegalStateException(host + "出问题了", throwable)
+ }
})
def body = tuple.first
def fontUrl = tuple.second
@@ -136,6 +134,11 @@ class GenAssetsTask extends DefaultTask {
}
return null
}
+ }, new Function() {
+ @Override
+ Throwable apply(Throwable throwable) {
+ return new IllegalStateException("拉取字体文件失败", throwable)
+ }
})
def fontFile = getTypefaceFile()
if (fontFile.exists()) {
@@ -148,12 +151,11 @@ class GenAssetsTask extends DefaultTask {
def xmlDir = getXmlDir()
if (xmlDir.exists()) {
xmlDir.deleteDir()
- } else {
- xmlDir.mkdir()
}
+ xmlDir.mkdir()
def fontName = getFontName()
for (def item : body.icons) {
- def name = toName(item.key)
+ def name = "ref_" + toName(item.key)
def file = new File(xmlDir, name + ".xml")
file.createNewFile()
def writer = file.newWriter()
@@ -173,6 +175,8 @@ class GenAssetsTask extends DefaultTask {
def b = (byte) c
if ((b >= 97 && b <= 122) || (b >= 65 && b <= 90)) {
builder.append(c.toLowerCase())
+ } else if (c.isDigit()) {
+ builder.append(c)
} else if (i != 0 && i != source.length() - 1) {
builder.append('_')
}
diff --git a/iconfont-assets/src/main/java/open/source/iconfont/assets/IconFontAsset.groovy b/iconfont-assets/src/main/groovy/open/source/iconfont/assets/IconFontAsset.groovy
similarity index 100%
rename from iconfont-assets/src/main/java/open/source/iconfont/assets/IconFontAsset.groovy
rename to iconfont-assets/src/main/groovy/open/source/iconfont/assets/IconFontAsset.groovy
diff --git a/iconfont-assets/src/main/java/open/source/iconfont/assets/IconFontAssetService.groovy b/iconfont-assets/src/main/groovy/open/source/iconfont/assets/IconFontAssetService.groovy
similarity index 100%
rename from iconfont-assets/src/main/java/open/source/iconfont/assets/IconFontAssetService.groovy
rename to iconfont-assets/src/main/groovy/open/source/iconfont/assets/IconFontAssetService.groovy
diff --git a/iconfont-assets/src/main/java/open/source/iconfont/assets/IconFontExtension.groovy b/iconfont-assets/src/main/groovy/open/source/iconfont/assets/IconFontExtension.groovy
similarity index 100%
rename from iconfont-assets/src/main/java/open/source/iconfont/assets/IconFontExtension.groovy
rename to iconfont-assets/src/main/groovy/open/source/iconfont/assets/IconFontExtension.groovy
diff --git a/iconfont-assets/src/main/java/resources/META-INF/gradle-plugins/open.source.iconfont.assets.properties b/iconfont-assets/src/main/resources/META-INF/gradle-plugins/open.source.iconfont.assets.properties
similarity index 100%
rename from iconfont-assets/src/main/java/resources/META-INF/gradle-plugins/open.source.iconfont.assets.properties
rename to iconfont-assets/src/main/resources/META-INF/gradle-plugins/open.source.iconfont.assets.properties
diff --git a/iconfont-assets/src/test/java/open/source/iconfont/assets/test/Main.java b/iconfont-assets/src/test/java/open/source/iconfont/assets/test/Main.java
new file mode 100644
index 0000000..dfe51bc
--- /dev/null
+++ b/iconfont-assets/src/test/java/open/source/iconfont/assets/test/Main.java
@@ -0,0 +1,31 @@
+package open.source.iconfont.assets.test;
+
+import com.google.gson.Gson;
+
+import java.io.IOException;
+
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import open.source.iconfont.assets.IconFontAssetService;
+import retrofit2.Retrofit;
+import retrofit2.converter.gson.GsonConverterFactory;
+
+public class Main {
+ public static void main(String[] args) {
+ OkHttpClient client = new OkHttpClient();
+ IconFontAssetService service = new Retrofit.Builder()
+ .client(client)
+ .baseUrl("https://icon-font-assets.oss-cn-beijing.aliyuncs.com")
+ .addConverterFactory(GsonConverterFactory.create(new Gson()))
+ .build()
+ .create(IconFontAssetService.class);
+ try {
+ System.out.println(service.index("0.0.1").execute().body().icons);
+ client.newCall(new Request.Builder()
+ .url("https://icon-font-assets.oss-cn-beijing.aliyuncs.com/icon-font-assets/iconfont.ttf")
+ .build()).execute();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/iconfont-export/.gitignore b/iconfont-export/.gitignore
index 6f8a813..62f9bec 100644
--- a/iconfont-export/.gitignore
+++ b/iconfont-export/.gitignore
@@ -1,2 +1,4 @@
-/build
-/.idea
\ No newline at end of file
+/node_modules
+yarn.lock
+/.idea
+/build
\ No newline at end of file
diff --git a/iconfont-export/assets/icons/daka-11.svg b/iconfont-export/assets/icons/daka-11.svg
new file mode 100644
index 0000000..2be6d96
--- /dev/null
+++ b/iconfont-export/assets/icons/daka-11.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/iconfont-export/assets/icons/fenxiang-05.svg b/iconfont-export/assets/icons/fenxiang-05.svg
new file mode 100644
index 0000000..9e1b2ac
--- /dev/null
+++ b/iconfont-export/assets/icons/fenxiang-05.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/iconfont-export/assets/icons/sousuo-02.svg b/iconfont-export/assets/icons/sousuo-02.svg
new file mode 100644
index 0000000..47e0791
--- /dev/null
+++ b/iconfont-export/assets/icons/sousuo-02.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/iconfont-export/assets/icons/xiaoxi-03.svg b/iconfont-export/assets/icons/xiaoxi-03.svg
new file mode 100644
index 0000000..45db76b
--- /dev/null
+++ b/iconfont-export/assets/icons/xiaoxi-03.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/iconfont-export/gulpfile.js b/iconfont-export/gulpfile.js
new file mode 100644
index 0000000..e2b1c24
--- /dev/null
+++ b/iconfont-export/gulpfile.js
@@ -0,0 +1,73 @@
+const iconfont = require('gulp-iconfont');
+const gulp = require('gulp');
+const fs = require('fs');
+const del = require('del');
+const path = require('path');
+const argv = require('minimist')(process.argv.slice(2));
+const input = argv['input'] || "assets/icons";
+const output = argv['output'] || 'build/';
+const fontName = argv['font-name'] || 'iconfont';
+const version = argv['version'] || '0.0.1';
+const outputWithVersion = path.join(output, version);
+
+/* Creates a unicode literal based on the string */
+function unicodeLiteral(str) {
+ function fixedHex(number, length) {
+ let str = number.toString(16).toUpperCase();
+ while (str.length < length)
+ str = "0" + str;
+ return str;
+ }
+
+ let i;
+ let result = "";
+ for (i = 0; i < str.length; ++i) {
+ /* You should probably replace this by an isASCII test */
+ if (str.charCodeAt(i) > 126 || str.charCodeAt(i) < 32)
+ result += fixedHex(str.charCodeAt(i), 4);
+ else
+ result += str[i];
+ }
+
+ return result.toLocaleLowerCase();
+}
+
+function saveJson(list) {
+ const icons = {};
+ for (let e of list) {
+ icons[e.name] = e.unicode
+ }
+ const json = {icons, version, fonts: ["./" + fontName + ".ttf"]};
+ const exportJson = path.join(outputWithVersion, "export.json");
+ if (fs.existsSync(exportJson)) {
+ fs.unlinkSync(exportJson);
+ }
+ fs.writeFileSync(exportJson, JSON.stringify(json));
+}
+
+gulp.task('clean', async () => {
+ await del([
+ path.join(output, '/**/*'),
+ ]);
+});
+
+gulp.task('iconfont', () => {
+ return gulp.src([path.join(input, '*.svg')])
+ .pipe(iconfont({
+ fontName: fontName,
+ formats: ['ttf'],
+ }))
+ .on('glyphs', function (glyphs, options) {
+ // CSS templating, e.g.
+ saveJson(glyphs.map((e) => {
+ return {
+ name: e.name,
+ unicode: unicodeLiteral(e.unicode[0])
+ }
+ }));
+ //console.log(glyphs, options);
+ })
+ .pipe(gulp.dest(outputWithVersion));
+});
+
+gulp.task("default", gulp.series("clean", "iconfont"));
diff --git a/iconfont-export/package.json b/iconfont-export/package.json
index b71f2da..6e832ed 100644
--- a/iconfont-export/package.json
+++ b/iconfont-export/package.json
@@ -1,20 +1,20 @@
{
- "name": "iconfont-export",
+ "name": "svg2iconfont",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
+ "test": "echo \"Error: no test specified\" && exit 1",
+ "iconfont": "gulp default"
},
+ "keywords": [],
+ "author": "",
+ "license": "ISC",
"dependencies": {
+ "del": "^6.0.0",
"gulp": "^4.0.2",
"gulp-filter": "^6.0.0",
"gulp-iconfont": "^11.0.0",
- "hasha": "^5.2.2",
- "minimist": "^1.2.5",
- "xmldom": "^0.4.0"
- },
- "keywords": [],
- "author": "",
- "license": "ISC"
+ "minimist": "^1.2.5"
+ }
}
diff --git a/iconfont/build.gradle b/iconfont/build.gradle
index 78b2868..5554d92 100644
--- a/iconfont/build.gradle
+++ b/iconfont/build.gradle
@@ -1,7 +1,8 @@
-plugins {
- id 'com.android.library'
- id 'kotlin-android'
-}
+apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
+apply plugin: 'com.github.dcendents.android-maven'
+
+group = rootProject.ext.groupId
android {
compileSdkVersion 30
@@ -33,10 +34,10 @@ android {
}
dependencies {
-
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.1.0'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
-}
\ No newline at end of file
+}
+
diff --git a/iconfont/src/main/java/open/source/iconfont/IconTextDrawable.kt b/iconfont/src/main/java/open/source/iconfont/IconTextDrawable.kt
index c67921e..c298210 100644
--- a/iconfont/src/main/java/open/source/iconfont/IconTextDrawable.kt
+++ b/iconfont/src/main/java/open/source/iconfont/IconTextDrawable.kt
@@ -37,17 +37,12 @@ class IconTextDrawable : Drawable, TintAwareDrawable {
private const val CODE_CACHE_SIZE = 128
- private val localContext = ThreadLocal()
-
private val codes = object : LruCache(CODE_CACHE_SIZE) {
override fun create(key: String): String {
return key.toInt(16).toChar().toString()
}
}
- private val inflateContext: Context
- get() = localContext.get() ?: AppCompatUtils.application
-
@JvmStatic
fun create(
context: Context,
@@ -84,16 +79,6 @@ class IconTextDrawable : Drawable, TintAwareDrawable {
return IconTextDrawable().apply { inflate(context, parser, attrs, theme) }
}
- @JvmStatic
- fun withContext(context: Context, action: Runnable) {
- try {
- localContext.set(context)
- action.run()
- } finally {
- localContext.set(null)
- }
- }
-
/**
* Parses a [android.graphics.PorterDuff.Mode] from a tintMode
* attribute's enum value.
@@ -240,6 +225,15 @@ class IconTextDrawable : Drawable, TintAwareDrawable {
shadowRadius = other.shadowRadius
paint.set(other.paint)
padding.set(other.padding)
+ centerX = other.centerX
+ centerY = other.centerY
+ useLevel = other.useLevel
+ angle = other.angle
+ orientation = other.orientation
+ gradientColors = other.gradientColors
+ positions = other.positions
+ gradientType = other.gradientType
+ gradientRadius = other.gradientRadius
}
override fun newDrawable(): Drawable {
@@ -323,7 +317,7 @@ class IconTextDrawable : Drawable, TintAwareDrawable {
parser: XmlPullParser,
attrs: AttributeSet
) {
- inflate(inflateContext, parser, attrs, null)
+ inflate(r, parser, attrs, null)
}
override fun inflate(
@@ -332,7 +326,7 @@ class IconTextDrawable : Drawable, TintAwareDrawable {
attrs: AttributeSet,
theme: Theme?
) {
- inflate(inflateContext, parser, attrs, theme)
+ inflate(InflateContext.obtain(r), parser, attrs, theme)
}
fun inflate(
@@ -343,6 +337,7 @@ class IconTextDrawable : Drawable, TintAwareDrawable {
) {
val array = obtainAttributes(context.resources, theme, attrs, R.styleable.IconTextDrawable)
try {
+ setVisible(array.getBoolean(R.styleable.IconTextDrawable_visible, true), false)
val text = array.getString(R.styleable.IconTextDrawable_code)
if (!text.isNullOrEmpty()) {
state.text = codes[text]
@@ -807,10 +802,13 @@ class IconTextDrawable : Drawable, TintAwareDrawable {
return field
}
set(@Px value) {
- field = 0f
- state.gradientRadius = value
- gradientIsDirty = true
- invalidateSelf()
+ if (Throwable().stackTrace.first().className != IconTextDrawable::class.java.name) {
+ state.gradientRadius = value
+ gradientIsDirty = true
+ invalidateSelf()
+ } else {
+ field = value
+ }
}
var gradientType: Int
diff --git a/iconfont/src/main/java/open/source/iconfont/InflateContext.kt b/iconfont/src/main/java/open/source/iconfont/InflateContext.kt
new file mode 100644
index 0000000..249c8d0
--- /dev/null
+++ b/iconfont/src/main/java/open/source/iconfont/InflateContext.kt
@@ -0,0 +1,36 @@
+package open.source.iconfont
+
+import android.content.Context
+import android.content.ContextWrapper
+import android.content.res.AssetManager
+import android.content.res.Resources
+import java.lang.ref.WeakReference
+import java.util.*
+
+internal class InflateContext(
+ base: Context,
+ res: Resources
+) : ContextWrapper(base) {
+
+ private val reference = WeakReference(res)
+
+ override fun getResources(): Resources {
+ return reference.get() ?: super.getResources()
+ }
+
+ override fun getAssets(): AssetManager {
+ return resources.assets
+ }
+
+ companion object {
+ private val caches = WeakHashMap()
+
+ fun obtain(r: Resources): Context {
+ synchronized(caches) {
+ return caches.getOrPut(r) {
+ InflateContext(AppCompatUtils.application, r)
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iconfont/src/main/java/open/source/iconfont/Ktx.kt b/iconfont/src/main/java/open/source/iconfont/Ktx.kt
new file mode 100644
index 0000000..49f6721
--- /dev/null
+++ b/iconfont/src/main/java/open/source/iconfont/Ktx.kt
@@ -0,0 +1,16 @@
+package open.source.iconfont
+
+import android.content.Context
+import android.content.res.Resources
+import android.graphics.drawable.Drawable
+import androidx.annotation.DrawableRes
+import androidx.annotation.XmlRes
+import androidx.appcompat.content.res.AppCompatResources
+
+fun Context.getAppCompatDrawable(@XmlRes @DrawableRes resId: Int): Drawable? {
+ return AppCompatResources.getDrawable(this, resId)
+}
+
+fun Resources.getAppCompatDrawable(@XmlRes @DrawableRes resId: Int): Drawable? {
+ return AppCompatResources.getDrawable(InflateContext.obtain(this), resId)
+}
\ No newline at end of file
diff --git a/iconfont/src/main/res/values/values.xml b/iconfont/src/main/res/values/values.xml
index dfe5f7d..915fb86 100644
--- a/iconfont/src/main/res/values/values.xml
+++ b/iconfont/src/main/res/values/values.xml
@@ -1,6 +1,7 @@
+