This repository has been archived by the owner on Dec 30, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 17
/
FontDrawable.java
196 lines (157 loc) · 5.77 KB
/
FontDrawable.java
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
package com.kazy.fontdrawable;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.support.annotation.ColorInt;
import static android.util.TypedValue.COMPLEX_UNIT_DIP;
import static android.util.TypedValue.applyDimension;
public class FontDrawable extends Drawable {
final private char fontCode;
final private Paint paint;
final private int size;
final private int padding;
private FontDrawable(Builder builder) {
this.fontCode = builder.fontCode;
this.paint = builder.paint;
this.paint.setColor(builder.color);
this.size = builder.size;
this.padding = builder.padding;
}
protected FontDrawable(char fontCode, Paint paint, int size, int padding) {
this.fontCode = fontCode;
this.paint = paint;
this.size = size;
this.padding = padding;
}
@Override
public void draw(Canvas canvas) {
canvas.drawPath(createTextPath(), paint);
}
private Path createTextPath() {
final Path path = createTextPathBase();
RectF textBounds = createTextBounds(path);
applyPadding(path, textBounds, createPaddingBounds());
applyOffset(path, textBounds);
path.close();
return path;
}
private Path createTextPathBase() {
Path path = new Path();
Rect viewBounds = getBounds();
float textSize = (float) viewBounds.height();
paint.setTextSize(textSize);
paint.getTextPath(String.valueOf(fontCode), 0, 1, 0, viewBounds.height(), path);
return path;
}
private RectF createTextBounds(Path path) {
RectF textBounds = new RectF();
path.computeBounds(textBounds, true);
return textBounds;
}
private void applyPadding(Path path, RectF textBounds, Rect paddingBounds) {
final Rect viewBounds = getBounds();
float deltaWidth = ((float) paddingBounds.width() / textBounds.width());
float deltaHeight = ((float) paddingBounds.height() / textBounds.height());
float attenuate = (deltaWidth < deltaHeight) ? deltaWidth : deltaHeight;
float textSize = paint.getTextSize();
textSize *= attenuate;
paint.setTextSize(textSize);
paint.getTextPath(String.valueOf(fontCode), 0, 1, 0, viewBounds.height(), path);
path.computeBounds(textBounds, true);
}
private void applyOffset(Path path, RectF textBounds) {
Rect viewBounds = getBounds();
float startX = viewBounds.centerX() - (textBounds.width() / 2);
float offsetX = startX - textBounds.left;
float startY = viewBounds.centerY() - (textBounds.height() / 2);
float offsetY = startY - (textBounds.top);
path.offset(offsetX, offsetY);
}
private Rect createPaddingBounds() {
Rect viewBounds = getBounds();
return new Rect(viewBounds.left + padding, viewBounds.top + padding, viewBounds.right - padding, viewBounds.bottom - padding);
}
public Bitmap toBitmap() {
final Bitmap bitmap = Bitmap.createBitmap(this.getIntrinsicWidth(), this.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
this.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
this.draw(canvas);
return bitmap;
}
@Override
public int getIntrinsicWidth() {
return size;
}
@Override
public int getIntrinsicHeight() {
return size;
}
@Override
public void setAlpha(int alpha) {
paint.setAlpha(alpha);
}
@Override
public void setColorFilter(ColorFilter colorFilter) {
paint.setColorFilter(colorFilter);
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
public static class Builder {
final private Context context;
final private char fontCode;
final private Paint paint;
private int size = 100;
private int padding = 0;
private int color = Color.BLACK;
public Builder(Context context, char fontCode, String customFontPath) {
this(context, fontCode, Typeface.createFromAsset(context.getAssets(), customFontPath));
}
public Builder(Context context, char fontCode, Typeface typeface) {
this(context, fontCode, new CustomFontPaint(typeface));
}
public Builder(Context context, char fontCode, CustomFontPaint paint) {
this.context = context;
this.fontCode = fontCode;
this.paint = new Paint(paint);
}
public Builder setSizePx(int size) {
this.size = size;
return this;
}
public Builder setSizeDp(int dp) {
int size = convertDpToPx(context, dp);
setSizePx(size);
return this;
}
public Builder setPaddingPx(int padding) {
this.padding = padding;
return this;
}
public Builder setPaddingDp(int dp) {
int padding = convertDpToPx(context, dp);
setPaddingPx(padding);
return this;
}
public Builder setColor(@ColorInt int color) {
this.color = color;
return this;
}
public FontDrawable build() {
return new FontDrawable(this);
}
private int convertDpToPx(Context context, float dp) {
return (int) applyDimension(COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics());
}
}
}