mirror of
https://github.com/zoriya/react-native-svg.git
synced 2026-06-08 09:10:44 +00:00
Improve variable font weight support
Refactor SVGLengthUnitType, AbsoluteFontWeight
This commit is contained in:
@@ -103,7 +103,7 @@ class Brush {
|
|||||||
|
|
||||||
private double getVal(SVGLength length, double relative, float scale, float textSize) {
|
private double getVal(SVGLength length, double relative, float scale, float textSize) {
|
||||||
return PropHelper.fromRelative(length, relative, 0, mUseObjectBoundingBox &&
|
return PropHelper.fromRelative(length, relative, 0, mUseObjectBoundingBox &&
|
||||||
length.unit == SVGLengthUnitType.SVG_LENGTHTYPE_NUMBER ? relative : scale, textSize);
|
length.unit == SVGLength.UnitType.NUMBER ? relative : scale, textSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupPaint(Paint paint, RectF pathBoundingBox, float scale, float opacity) {
|
void setupPaint(Paint paint, RectF pathBoundingBox, float scale, float opacity) {
|
||||||
|
|||||||
@@ -9,69 +9,70 @@ import static com.facebook.react.uimanager.ViewProps.FONT_STYLE;
|
|||||||
import static com.facebook.react.uimanager.ViewProps.FONT_WEIGHT;
|
import static com.facebook.react.uimanager.ViewProps.FONT_WEIGHT;
|
||||||
import static com.horcrux.svg.TextProperties.*;
|
import static com.horcrux.svg.TextProperties.*;
|
||||||
|
|
||||||
class AbsoluteFontWeight {
|
|
||||||
|
|
||||||
static int normal = 400;
|
|
||||||
|
|
||||||
private static final FontWeight[] WEIGHTS = new FontWeight[]{
|
|
||||||
FontWeight.w100,
|
|
||||||
FontWeight.w100,
|
|
||||||
FontWeight.w200,
|
|
||||||
FontWeight.w300,
|
|
||||||
FontWeight.Normal,
|
|
||||||
FontWeight.w500,
|
|
||||||
FontWeight.w600,
|
|
||||||
FontWeight.Bold,
|
|
||||||
FontWeight.w800,
|
|
||||||
FontWeight.w900,
|
|
||||||
FontWeight.w900,
|
|
||||||
};
|
|
||||||
|
|
||||||
static FontWeight nearestFontWeight(int absoluteFontWeight) {
|
|
||||||
return WEIGHTS[Math.round(absoluteFontWeight / 100f)];
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final int[] absoluteFontWeights = new int[]{
|
|
||||||
400, 700, 100, 200, 300, 400, 500, 600, 700, 800, 900
|
|
||||||
};
|
|
||||||
|
|
||||||
// https://drafts.csswg.org/css-fonts-4/#relative-weights
|
|
||||||
static int from(FontWeight fontWeight, FontData parent) {
|
|
||||||
if (fontWeight == FontWeight.Bolder) {
|
|
||||||
return bolder(parent.absoluteFontWeight);
|
|
||||||
} else if (fontWeight == FontWeight.Lighter) {
|
|
||||||
return lighter(parent.absoluteFontWeight);
|
|
||||||
} else {
|
|
||||||
return absoluteFontWeights[fontWeight.ordinal()];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int bolder(int inherited) {
|
|
||||||
if (inherited < 350) {
|
|
||||||
return 400;
|
|
||||||
} else if (inherited < 550) {
|
|
||||||
return 700;
|
|
||||||
} else if (inherited < 900) {
|
|
||||||
return 900;
|
|
||||||
} else {
|
|
||||||
return inherited;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int lighter(int inherited) {
|
|
||||||
if (inherited < 100) {
|
|
||||||
return inherited;
|
|
||||||
} else if (inherited < 550) {
|
|
||||||
return 100;
|
|
||||||
} else if (inherited < 750) {
|
|
||||||
return 400;
|
|
||||||
} else {
|
|
||||||
return 700;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class FontData {
|
class FontData {
|
||||||
|
|
||||||
|
static class AbsoluteFontWeight {
|
||||||
|
|
||||||
|
static final int normal = 400;
|
||||||
|
|
||||||
|
private static final FontWeight[] WEIGHTS = new FontWeight[]{
|
||||||
|
FontWeight.w100,
|
||||||
|
FontWeight.w100,
|
||||||
|
FontWeight.w200,
|
||||||
|
FontWeight.w300,
|
||||||
|
FontWeight.Normal,
|
||||||
|
FontWeight.w500,
|
||||||
|
FontWeight.w600,
|
||||||
|
FontWeight.Bold,
|
||||||
|
FontWeight.w800,
|
||||||
|
FontWeight.w900,
|
||||||
|
FontWeight.w900,
|
||||||
|
};
|
||||||
|
|
||||||
|
static FontWeight nearestFontWeight(int absoluteFontWeight) {
|
||||||
|
return WEIGHTS[Math.round(absoluteFontWeight / 100f)];
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final int[] absoluteFontWeights = new int[]{
|
||||||
|
400, 700, 100, 200, 300, 400, 500, 600, 700, 800, 900
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://drafts.csswg.org/css-fonts-4/#relative-weights
|
||||||
|
static int from(FontWeight fontWeight, FontData parent) {
|
||||||
|
if (fontWeight == FontWeight.Bolder) {
|
||||||
|
return bolder(parent.absoluteFontWeight);
|
||||||
|
} else if (fontWeight == FontWeight.Lighter) {
|
||||||
|
return lighter(parent.absoluteFontWeight);
|
||||||
|
} else {
|
||||||
|
return absoluteFontWeights[fontWeight.ordinal()];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int bolder(int inherited) {
|
||||||
|
if (inherited < 350) {
|
||||||
|
return 400;
|
||||||
|
} else if (inherited < 550) {
|
||||||
|
return 700;
|
||||||
|
} else if (inherited < 900) {
|
||||||
|
return 900;
|
||||||
|
} else {
|
||||||
|
return inherited;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int lighter(int inherited) {
|
||||||
|
if (inherited < 100) {
|
||||||
|
return inherited;
|
||||||
|
} else if (inherited < 550) {
|
||||||
|
return 100;
|
||||||
|
} else if (inherited < 750) {
|
||||||
|
return 400;
|
||||||
|
} else {
|
||||||
|
return 700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static final double DEFAULT_FONT_SIZE = 12d;
|
static final double DEFAULT_FONT_SIZE = 12d;
|
||||||
|
|
||||||
private static final double DEFAULT_KERNING = 0d;
|
private static final double DEFAULT_KERNING = 0d;
|
||||||
|
|||||||
@@ -186,42 +186,42 @@ class PropHelper {
|
|||||||
if (length == null) {
|
if (length == null) {
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
SVGLengthUnitType unitType = length.unit;
|
SVGLength.UnitType unitType = length.unit;
|
||||||
double value = length.value;
|
double value = length.value;
|
||||||
double unit = 1;
|
double unit = 1;
|
||||||
switch (unitType) {
|
switch (unitType) {
|
||||||
case SVG_LENGTHTYPE_NUMBER:
|
case NUMBER:
|
||||||
case SVG_LENGTHTYPE_PX:
|
case PX:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SVG_LENGTHTYPE_PERCENTAGE:
|
case PERCENTAGE:
|
||||||
return value / 100 * relative + offset;
|
return value / 100 * relative + offset;
|
||||||
|
|
||||||
case SVG_LENGTHTYPE_EMS:
|
case EMS:
|
||||||
unit = fontSize;
|
unit = fontSize;
|
||||||
break;
|
break;
|
||||||
case SVG_LENGTHTYPE_EXS:
|
case EXS:
|
||||||
unit = fontSize / 2;
|
unit = fontSize / 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SVG_LENGTHTYPE_CM:
|
case CM:
|
||||||
unit = 35.43307;
|
unit = 35.43307;
|
||||||
break;
|
break;
|
||||||
case SVG_LENGTHTYPE_MM:
|
case MM:
|
||||||
unit = 3.543307;
|
unit = 3.543307;
|
||||||
break;
|
break;
|
||||||
case SVG_LENGTHTYPE_IN:
|
case IN:
|
||||||
unit = 90;
|
unit = 90;
|
||||||
break;
|
break;
|
||||||
case SVG_LENGTHTYPE_PT:
|
case PT:
|
||||||
unit = 1.25;
|
unit = 1.25;
|
||||||
break;
|
break;
|
||||||
case SVG_LENGTHTYPE_PC:
|
case PC:
|
||||||
unit = 15;
|
unit = 15;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
case SVG_LENGTHTYPE_UNKNOWN:
|
case UNKNOWN:
|
||||||
return value * scale + offset;
|
return value * scale + offset;
|
||||||
}
|
}
|
||||||
return value * unit * scale + offset;
|
return value * unit * scale + offset;
|
||||||
|
|||||||
@@ -5,41 +5,41 @@ import com.facebook.react.bridge.ReadableArray;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
// https://www.w3.org/TR/SVG/types.html#InterfaceSVGLength
|
|
||||||
enum SVGLengthUnitType {
|
|
||||||
SVG_LENGTHTYPE_UNKNOWN,
|
|
||||||
SVG_LENGTHTYPE_NUMBER,
|
|
||||||
SVG_LENGTHTYPE_PERCENTAGE,
|
|
||||||
SVG_LENGTHTYPE_EMS,
|
|
||||||
SVG_LENGTHTYPE_EXS,
|
|
||||||
SVG_LENGTHTYPE_PX,
|
|
||||||
SVG_LENGTHTYPE_CM,
|
|
||||||
SVG_LENGTHTYPE_MM,
|
|
||||||
SVG_LENGTHTYPE_IN,
|
|
||||||
SVG_LENGTHTYPE_PT,
|
|
||||||
SVG_LENGTHTYPE_PC,
|
|
||||||
}
|
|
||||||
|
|
||||||
class SVGLength {
|
class SVGLength {
|
||||||
|
// https://www.w3.org/TR/SVG/types.html#InterfaceSVGLength
|
||||||
|
public enum UnitType {
|
||||||
|
UNKNOWN,
|
||||||
|
NUMBER,
|
||||||
|
PERCENTAGE,
|
||||||
|
EMS,
|
||||||
|
EXS,
|
||||||
|
PX,
|
||||||
|
CM,
|
||||||
|
MM,
|
||||||
|
IN,
|
||||||
|
PT,
|
||||||
|
PC,
|
||||||
|
}
|
||||||
|
|
||||||
final double value;
|
final double value;
|
||||||
final SVGLengthUnitType unit;
|
final UnitType unit;
|
||||||
private SVGLength() {
|
private SVGLength() {
|
||||||
value = 0;
|
value = 0;
|
||||||
unit = SVGLengthUnitType.SVG_LENGTHTYPE_UNKNOWN;
|
unit = UnitType.UNKNOWN;
|
||||||
}
|
}
|
||||||
SVGLength(double number) {
|
SVGLength(double number) {
|
||||||
value = number;
|
value = number;
|
||||||
unit = SVGLengthUnitType.SVG_LENGTHTYPE_NUMBER;
|
unit = UnitType.NUMBER;
|
||||||
}
|
}
|
||||||
private SVGLength(String length) {
|
private SVGLength(String length) {
|
||||||
length = length.trim();
|
length = length.trim();
|
||||||
int stringLength = length.length();
|
int stringLength = length.length();
|
||||||
int percentIndex = stringLength - 1;
|
int percentIndex = stringLength - 1;
|
||||||
if (stringLength == 0 || length.equals("normal")) {
|
if (stringLength == 0 || length.equals("normal")) {
|
||||||
unit = SVGLengthUnitType.SVG_LENGTHTYPE_UNKNOWN;
|
unit = UnitType.UNKNOWN;
|
||||||
value = 0;
|
value = 0;
|
||||||
} else if (length.codePointAt(percentIndex) == '%') {
|
} else if (length.codePointAt(percentIndex) == '%') {
|
||||||
unit = SVGLengthUnitType.SVG_LENGTHTYPE_PERCENTAGE;
|
unit = UnitType.PERCENTAGE;
|
||||||
value = Double.valueOf(length.substring(0, percentIndex));
|
value = Double.valueOf(length.substring(0, percentIndex));
|
||||||
} else {
|
} else {
|
||||||
int twoLetterUnitIndex = stringLength - 2;
|
int twoLetterUnitIndex = stringLength - 2;
|
||||||
@@ -48,43 +48,43 @@ class SVGLength {
|
|||||||
int end = twoLetterUnitIndex;
|
int end = twoLetterUnitIndex;
|
||||||
switch (lastTwo) {
|
switch (lastTwo) {
|
||||||
case "px":
|
case "px":
|
||||||
unit = SVGLengthUnitType.SVG_LENGTHTYPE_NUMBER;
|
unit = UnitType.NUMBER;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "em":
|
case "em":
|
||||||
unit = SVGLengthUnitType.SVG_LENGTHTYPE_EMS;
|
unit = UnitType.EMS;
|
||||||
break;
|
break;
|
||||||
case "ex":
|
case "ex":
|
||||||
unit = SVGLengthUnitType.SVG_LENGTHTYPE_EXS;
|
unit = UnitType.EXS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "pt":
|
case "pt":
|
||||||
unit = SVGLengthUnitType.SVG_LENGTHTYPE_PT;
|
unit = UnitType.PT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "pc":
|
case "pc":
|
||||||
unit = SVGLengthUnitType.SVG_LENGTHTYPE_PC;
|
unit = UnitType.PC;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "mm":
|
case "mm":
|
||||||
unit = SVGLengthUnitType.SVG_LENGTHTYPE_MM;
|
unit = UnitType.MM;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "cm":
|
case "cm":
|
||||||
unit = SVGLengthUnitType.SVG_LENGTHTYPE_CM;
|
unit = UnitType.CM;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "in":
|
case "in":
|
||||||
unit = SVGLengthUnitType.SVG_LENGTHTYPE_IN;
|
unit = UnitType.IN;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
unit = SVGLengthUnitType.SVG_LENGTHTYPE_NUMBER;
|
unit = UnitType.NUMBER;
|
||||||
end = stringLength;
|
end = stringLength;
|
||||||
}
|
}
|
||||||
value = Double.valueOf(length.substring(0, end));
|
value = Double.valueOf(length.substring(0, end));
|
||||||
} else {
|
} else {
|
||||||
unit = SVGLengthUnitType.SVG_LENGTHTYPE_NUMBER;
|
unit = UnitType.NUMBER;
|
||||||
value = Double.valueOf(length);
|
value = Double.valueOf(length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ class TSpanView extends TextView {
|
|||||||
}
|
}
|
||||||
paint.setLetterSpacing((float)(letterSpacing / (font.fontSize * mScale)));
|
paint.setLetterSpacing((float)(letterSpacing / (font.fontSize * mScale)));
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
paint.setFontVariationSettings("'wght' " + font.absoluteFontWeight + ", " + font.fontVariationSettings);
|
paint.setFontVariationSettings("'wght' " + font.absoluteFontWeight + font.fontVariationSettings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -347,7 +347,7 @@ class TSpanView extends TextView {
|
|||||||
paint.setFontFeatureSettings(defaultFeatures + disableDiscretionaryLigatures + font.fontFeatureSettings);
|
paint.setFontFeatureSettings(defaultFeatures + disableDiscretionaryLigatures + font.fontFeatureSettings);
|
||||||
}
|
}
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
paint.setFontVariationSettings("'wght' " + font.absoluteFontWeight + ", " + font.fontVariationSettings);
|
paint.setFontVariationSettings("'wght' " + font.absoluteFontWeight + font.fontVariationSettings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// OpenType.js font data
|
// OpenType.js font data
|
||||||
@@ -1000,22 +1000,48 @@ class TSpanView extends TextView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Typeface typeface = null;
|
Typeface typeface = null;
|
||||||
|
int weight = font.absoluteFontWeight;
|
||||||
final String fontFamily = font.fontFamily;
|
final String fontFamily = font.fontFamily;
|
||||||
try {
|
String otfpath = FONTS + fontFamily + OTF;
|
||||||
String path = FONTS + fontFamily + OTF;
|
String ttfpath = FONTS + fontFamily + TTF;
|
||||||
typeface = Typeface.createFromAsset(assetManager, path);
|
|
||||||
} catch (Exception ignored) {
|
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
||||||
|
Typeface.Builder builder = new Typeface.Builder(assetManager, otfpath);
|
||||||
|
builder.setFontVariationSettings("'wght' " + weight);
|
||||||
|
builder.setWeight(weight);
|
||||||
|
builder.setItalic(isItalic);
|
||||||
|
typeface = builder.build();
|
||||||
|
if (typeface == null) {
|
||||||
|
builder = new Typeface.Builder(assetManager, ttfpath);
|
||||||
|
builder.setFontVariationSettings("'wght' " + weight);
|
||||||
|
builder.setWeight(weight);
|
||||||
|
builder.setItalic(isItalic);
|
||||||
|
typeface = builder.build();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
try {
|
try {
|
||||||
String path = FONTS + fontFamily + TTF;
|
typeface = Typeface.createFromAsset(assetManager, otfpath);
|
||||||
typeface = Typeface.createFromAsset(assetManager, path);
|
} catch (Exception ignored) {
|
||||||
} catch (Exception ignored2) {
|
|
||||||
try {
|
try {
|
||||||
typeface = ReactFontManager.getInstance().getTypeface(fontFamily, fontStyle, assetManager);
|
typeface = Typeface.createFromAsset(assetManager, ttfpath);
|
||||||
} catch (Exception ignored3) {
|
} catch (Exception ignored2) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeface == null) {
|
||||||
|
try {
|
||||||
|
typeface = ReactFontManager.getInstance().getTypeface(fontFamily, fontStyle, weight, assetManager);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||||
|
typeface = Typeface.create(typeface, weight, isItalic);
|
||||||
|
} else {
|
||||||
|
typeface = Typeface.create(typeface, fontStyle);
|
||||||
|
}
|
||||||
|
|
||||||
// NB: if the font family is null / unsupported, the default one will be used
|
// NB: if the font family is null / unsupported, the default one will be used
|
||||||
paint.setTypeface(typeface);
|
paint.setTypeface(typeface);
|
||||||
paint.setTextSize((float) fontSize);
|
paint.setTextSize((float) fontSize);
|
||||||
|
|||||||
@@ -345,30 +345,30 @@ abstract public class VirtualView extends ReactViewGroup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
double relativeOnWidth(SVGLength length) {
|
double relativeOnWidth(SVGLength length) {
|
||||||
SVGLengthUnitType unit = length.unit;
|
SVGLength.UnitType unit = length.unit;
|
||||||
if (unit == SVGLengthUnitType.SVG_LENGTHTYPE_NUMBER){
|
if (unit == SVGLength.UnitType.NUMBER){
|
||||||
return length.value * mScale;
|
return length.value * mScale;
|
||||||
} else if (unit == SVGLengthUnitType.SVG_LENGTHTYPE_PERCENTAGE){
|
} else if (unit == SVGLength.UnitType.PERCENTAGE){
|
||||||
return length.value / 100 * getCanvasWidth();
|
return length.value / 100 * getCanvasWidth();
|
||||||
}
|
}
|
||||||
return fromRelativeFast(length);
|
return fromRelativeFast(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
double relativeOnHeight(SVGLength length) {
|
double relativeOnHeight(SVGLength length) {
|
||||||
SVGLengthUnitType unit = length.unit;
|
SVGLength.UnitType unit = length.unit;
|
||||||
if (unit == SVGLengthUnitType.SVG_LENGTHTYPE_NUMBER){
|
if (unit == SVGLength.UnitType.NUMBER){
|
||||||
return length.value * mScale;
|
return length.value * mScale;
|
||||||
} else if (unit == SVGLengthUnitType.SVG_LENGTHTYPE_PERCENTAGE){
|
} else if (unit == SVGLength.UnitType.PERCENTAGE){
|
||||||
return length.value / 100 * getCanvasHeight();
|
return length.value / 100 * getCanvasHeight();
|
||||||
}
|
}
|
||||||
return fromRelativeFast(length);
|
return fromRelativeFast(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
double relativeOnOther(SVGLength length) {
|
double relativeOnOther(SVGLength length) {
|
||||||
SVGLengthUnitType unit = length.unit;
|
SVGLength.UnitType unit = length.unit;
|
||||||
if (unit == SVGLengthUnitType.SVG_LENGTHTYPE_NUMBER){
|
if (unit == SVGLength.UnitType.NUMBER){
|
||||||
return length.value * mScale;
|
return length.value * mScale;
|
||||||
} else if (unit == SVGLengthUnitType.SVG_LENGTHTYPE_PERCENTAGE){
|
} else if (unit == SVGLength.UnitType.PERCENTAGE){
|
||||||
return length.value / 100 * getCanvasDiagonal();
|
return length.value / 100 * getCanvasDiagonal();
|
||||||
}
|
}
|
||||||
return fromRelativeFast(length);
|
return fromRelativeFast(length);
|
||||||
@@ -384,26 +384,26 @@ abstract public class VirtualView extends ReactViewGroup {
|
|||||||
private double fromRelativeFast(SVGLength length) {
|
private double fromRelativeFast(SVGLength length) {
|
||||||
double unit;
|
double unit;
|
||||||
switch (length.unit) {
|
switch (length.unit) {
|
||||||
case SVG_LENGTHTYPE_EMS:
|
case EMS:
|
||||||
unit = getFontSizeFromContext();
|
unit = getFontSizeFromContext();
|
||||||
break;
|
break;
|
||||||
case SVG_LENGTHTYPE_EXS:
|
case EXS:
|
||||||
unit = getFontSizeFromContext() / 2;
|
unit = getFontSizeFromContext() / 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SVG_LENGTHTYPE_CM:
|
case CM:
|
||||||
unit = 35.43307;
|
unit = 35.43307;
|
||||||
break;
|
break;
|
||||||
case SVG_LENGTHTYPE_MM:
|
case MM:
|
||||||
unit = 3.543307;
|
unit = 3.543307;
|
||||||
break;
|
break;
|
||||||
case SVG_LENGTHTYPE_IN:
|
case IN:
|
||||||
unit = 90;
|
unit = 90;
|
||||||
break;
|
break;
|
||||||
case SVG_LENGTHTYPE_PT:
|
case PT:
|
||||||
unit = 1.25;
|
unit = 1.25;
|
||||||
break;
|
break;
|
||||||
case SVG_LENGTHTYPE_PC:
|
case PC:
|
||||||
unit = 15;
|
unit = 15;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -134,13 +134,105 @@
|
|||||||
}
|
}
|
||||||
fontFamily = fontFamilyFound ? fontFamily : nil;
|
fontFamily = fontFamilyFound ? fontFamily : nil;
|
||||||
|
|
||||||
return (__bridge CTFontRef)[RCTFont updateFont:nil
|
UIFont *font = [RCTFont updateFont:nil
|
||||||
withFamily:fontFamily
|
withFamily:fontFamily
|
||||||
size:fontSize
|
size:fontSize
|
||||||
weight:fontWeight
|
weight:fontWeight
|
||||||
style:fontStyle
|
style:fontStyle
|
||||||
variant:nil
|
variant:nil
|
||||||
scaleMultiplier:1.0];
|
scaleMultiplier:1.0];
|
||||||
|
|
||||||
|
CTFontRef ref = (__bridge CTFontRef)font;
|
||||||
|
|
||||||
|
int weight = topFont_->absoluteFontWeight;
|
||||||
|
if (weight == 400) {
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
CFArrayRef cgAxes = CTFontCopyVariationAxes(ref);
|
||||||
|
CFIndex cgAxisCount = CFArrayGetCount(cgAxes);
|
||||||
|
CFNumberRef wght_id = 0;
|
||||||
|
|
||||||
|
for (CFIndex i = 0; i < cgAxisCount; ++i) {
|
||||||
|
CFTypeRef cgAxis = CFArrayGetValueAtIndex(cgAxes, i);
|
||||||
|
if (CFGetTypeID(cgAxis) != CFDictionaryGetTypeID()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
CFDictionaryRef cgAxisDict = (CFDictionaryRef)cgAxis;
|
||||||
|
CFTypeRef axisName = CFDictionaryGetValue(cgAxisDict, kCTFontVariationAxisNameKey);
|
||||||
|
CFTypeRef axisId = CFDictionaryGetValue(cgAxisDict, kCTFontVariationAxisIdentifierKey);
|
||||||
|
|
||||||
|
if (!axisName || CFGetTypeID(axisName) != CFStringGetTypeID()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
CFStringRef axisNameString = (CFStringRef)axisName;
|
||||||
|
NSString *axisNameNSString = (__bridge NSString *)(axisNameString);
|
||||||
|
if (![@"Weight" isEqualToString:axisNameNSString]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!axisId || CFGetTypeID(axisId) != CFNumberGetTypeID()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
wght_id = (CFNumberRef)axisId;
|
||||||
|
break;
|
||||||
|
/*
|
||||||
|
int axisIdInt;
|
||||||
|
if (!CFNumberGetValue(wght_id, kCFNumberIntType, &axisIdInt))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
CFTypeRef axisDefaultValue = CFDictionaryGetValue(cgAxisDict,
|
||||||
|
kCTFontVariationAxisDefaultValueKey);
|
||||||
|
CFTypeRef axisMinValue = CFDictionaryGetValue(cgAxisDict,
|
||||||
|
kCTFontVariationAxisMinimumValueKey);
|
||||||
|
CFTypeRef axisMaxValue = CFDictionaryGetValue(cgAxisDict,
|
||||||
|
kCTFontVariationAxisMaximumValueKey);
|
||||||
|
|
||||||
|
if (!axisDefaultValue || CFGetTypeID(axisDefaultValue) != CFNumberGetTypeID()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
CFNumberRef axisDefaultValueNumber = (CFNumberRef)axisDefaultValue;
|
||||||
|
double axisDefaultValueDouble;
|
||||||
|
if (!CFNumberGetValue(axisDefaultValueNumber, kCFNumberDoubleType, &axisDefaultValueDouble))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!axisMinValue || CFGetTypeID(axisMinValue) != CFNumberGetTypeID()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
CFNumberRef axisMinValueNumber = (CFNumberRef)axisMinValue;
|
||||||
|
double axisMinValueDouble;
|
||||||
|
if (!CFNumberGetValue(axisMinValueNumber, kCFNumberDoubleType, &axisMinValueDouble))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!axisMaxValue || CFGetTypeID(axisMaxValue) != CFNumberGetTypeID()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
CFNumberRef axisMaxValueNumber = (CFNumberRef)axisMaxValue;
|
||||||
|
double axisMaxValueDouble;
|
||||||
|
if (!CFNumberGetValue(axisMaxValueNumber, kCFNumberDoubleType, &axisMaxValueDouble))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
RCTLog(@"name: %@ min: %f max: %f def: %f id: %i", axisNameNSString, axisMinValueDouble, axisMaxValueDouble, axisDefaultValueDouble, axisIdInt);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wght_id == 0) {
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
UIFontDescriptor *uifd = font.fontDescriptor;
|
||||||
|
CTFontDescriptorRef ctfd = (__bridge CTFontDescriptorRef)(uifd);
|
||||||
|
CTFontDescriptorRef newfd = CTFontDescriptorCreateCopyWithVariation(ctfd, wght_id, (CGFloat)weight);
|
||||||
|
CTFontRef newfont = CTFontCreateCopyWithAttributes(ref, (CGFloat)[fontSize doubleValue], nil, newfd);
|
||||||
|
return newfont;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)pushIndices
|
- (void)pushIndices
|
||||||
|
|||||||
@@ -157,18 +157,6 @@ static CGFloat RNSVGTSpan_radToDeg = 180 / (CGFloat)M_PI;
|
|||||||
{
|
{
|
||||||
[attrs setObject:kernAttr forKey:(id)kCTKernAttributeName];
|
[attrs setObject:kernAttr forKey:(id)kCTKernAttributeName];
|
||||||
}
|
}
|
||||||
|
|
||||||
int weight = font->absoluteFontWeight;
|
|
||||||
if (weight != 400) {
|
|
||||||
// https://github.com/WebKit/webkit/blob/73b06fb2cc31aaff91119718d9abdc7be703d41b/Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp#L429-L444
|
|
||||||
float denormalizedWeight = (weight + 109.3) / 523.7;
|
|
||||||
CFMutableDictionaryRef variationDictionary = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
|
|
||||||
long long bitwiseTag = 'w' << 24 | 'g' << 16 | 'h' << 8 | 't';
|
|
||||||
CFNumberRef tagNumber = CFNumberCreate(kCFAllocatorDefault, kCFNumberLongLongType, &bitwiseTag);
|
|
||||||
CFNumberRef valueNumber = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloatType, &denormalizedWeight);
|
|
||||||
CFDictionarySetValue(variationDictionary, tagNumber, valueNumber);
|
|
||||||
CFDictionaryAddValue(attributes, kCTFontVariationAttribute, variationDictionary);
|
|
||||||
}
|
|
||||||
|
|
||||||
CFStringRef string = (__bridge CFStringRef)str;
|
CFStringRef string = (__bridge CFStringRef)str;
|
||||||
CFAttributedStringRef attrString = CFAttributedStringCreate(kCFAllocatorDefault, string, attributes);
|
CFAttributedStringRef attrString = CFAttributedStringCreate(kCFAllocatorDefault, string, attributes);
|
||||||
@@ -341,18 +329,6 @@ static CGFloat RNSVGTSpan_radToDeg = 180 / (CGFloat)M_PI;
|
|||||||
[attrs setObject:noAutoKern forKey:(id)kCTKernAttributeName];
|
[attrs setObject:noAutoKern forKey:(id)kCTKernAttributeName];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int weight = font->absoluteFontWeight;
|
|
||||||
if (weight != 400) {
|
|
||||||
// https://github.com/WebKit/webkit/blob/73b06fb2cc31aaff91119718d9abdc7be703d41b/Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp#L429-L444
|
|
||||||
float denormalizedWeight = (weight + 109.3) / 523.7;
|
|
||||||
CFMutableDictionaryRef variationDictionary = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
|
|
||||||
long long bitwiseTag = 'w' << 24 | 'g' << 16 | 'h' << 8 | 't';
|
|
||||||
CFNumberRef tagNumber = CFNumberCreate(kCFAllocatorDefault, kCFNumberLongLongType, &bitwiseTag);
|
|
||||||
CFNumberRef valueNumber = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloatType, &denormalizedWeight);
|
|
||||||
CFDictionarySetValue(variationDictionary, tagNumber, valueNumber);
|
|
||||||
CFDictionaryAddValue(attributes, kCTFontVariationAttribute, variationDictionary);
|
|
||||||
}
|
|
||||||
|
|
||||||
CFStringRef string = (__bridge CFStringRef)str;
|
CFStringRef string = (__bridge CFStringRef)str;
|
||||||
CFAttributedStringRef attrString = CFAttributedStringCreate(kCFAllocatorDefault, string, attributes);
|
CFAttributedStringRef attrString = CFAttributedStringCreate(kCFAllocatorDefault, string, attributes);
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ RCT_CUSTOM_VIEW_PROPERTY(baselineShift, id, RNSVGText)
|
|||||||
RCT_EXPORT_VIEW_PROPERTY(lengthAdjust, NSString)
|
RCT_EXPORT_VIEW_PROPERTY(lengthAdjust, NSString)
|
||||||
RCT_EXPORT_VIEW_PROPERTY(alignmentBaseline, NSString)
|
RCT_EXPORT_VIEW_PROPERTY(alignmentBaseline, NSString)
|
||||||
|
|
||||||
RCT_CUSTOM_VIEW_PROPERTY(fontSize, id, RNSVGGroup)
|
RCT_CUSTOM_VIEW_PROPERTY(fontSize, id, RNSVGText)
|
||||||
{
|
{
|
||||||
if ([json isKindOfClass:[NSString class]]) {
|
if ([json isKindOfClass:[NSString class]]) {
|
||||||
NSString *stringValue = (NSString *)json;
|
NSString *stringValue = (NSString *)json;
|
||||||
@@ -80,7 +80,7 @@ RCT_CUSTOM_VIEW_PROPERTY(fontSize, id, RNSVGGroup)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RCT_CUSTOM_VIEW_PROPERTY(fontWeight, id, RNSVGGroup)
|
RCT_CUSTOM_VIEW_PROPERTY(fontWeight, id, RNSVGText)
|
||||||
{
|
{
|
||||||
if ([json isKindOfClass:[NSString class]]) {
|
if ([json isKindOfClass:[NSString class]]) {
|
||||||
NSString *stringValue = (NSString *)json;
|
NSString *stringValue = (NSString *)json;
|
||||||
|
|||||||
Reference in New Issue
Block a user