diff --git a/src/java.desktop/share/classes/java/awt/Font.java b/src/java.desktop/share/classes/java/awt/Font.java index 2da68fd861800..1067bf6c9fcf5 100644 --- a/src/java.desktop/share/classes/java/awt/Font.java +++ b/src/java.desktop/share/classes/java/awt/Font.java @@ -767,7 +767,8 @@ protected Font(Font font) { EBIDI_EMBEDDING, EJUSTIFICATION, EINPUT_METHOD_HIGHLIGHT, EINPUT_METHOD_UNDERLINE, ESWAP_COLORS, ENUMERIC_SHAPING, EKERNING, - ELIGATURES, ETRACKING, ESUPERSCRIPT); + ELIGATURES, ETRACKING, ESUPERSCRIPT, + EPROPORTIONAL_FIGURES, ETABULAR_FIGURES); private static final int EXTRA_MASK = AttributeValues.getMask(ETRANSFORM, ESUPERSCRIPT, EWIDTH); diff --git a/src/java.desktop/share/classes/java/awt/font/TextAttribute.java b/src/java.desktop/share/classes/java/awt/font/TextAttribute.java index 6efb0ba4af4f7..6aa562672f7b7 100644 --- a/src/java.desktop/share/classes/java/awt/font/TextAttribute.java +++ b/src/java.desktop/share/classes/java/awt/font/TextAttribute.java @@ -1111,4 +1111,50 @@ protected Object readResolve() throws InvalidObjectException { */ public static final Float TRACKING_LOOSE = Float.valueOf(.04f); + + /** + * Attribute key for enabling optional proportional figures. Values are + * instances of {@code Integer}. The default value is + * {@code 0}, which means do not use optional proportional figures. + * + *

The constant value {@link #PROPORTIONAL_FIGURES_ON} is defined. + * + *

Conflicts with {@link #TABULAR_FIGURES} + * + * @since 26 + */ + public static final TextAttribute PROPORTIONAL_FIGURES = + new TextAttribute("proportional-figures"); + + /** + * Request to enable proprotional figures. + * + * @see #PROPORTIONAL_FIGURES + * @since 26 + */ + public static final Integer PROPORTIONAL_FIGURES_ON = + Integer.valueOf(1); + + /** + * Attribute key for enabling optional tabular figures. Values are + * instances of {@code Integer}. The default value is + * {@code 0}, which means do not use optional tabular figures. + * + *

The constant value {@link #TABULAR_FIGURES_ON} is defined. + * + *

Conflicts with {@link #PROPORTIONAL_FIGURES} + * + * @since 26 + */ + public static final TextAttribute TABULAR_FIGURES = + new TextAttribute("tabular-figures"); + + /** + * Request to enable tabular figures. + * + * @see #TABULAR_FIGURES + * @since 26 + */ + public static final Integer TABULAR_FIGURES_ON = + Integer.valueOf(1); } diff --git a/src/java.desktop/share/classes/sun/font/AttributeValues.java b/src/java.desktop/share/classes/sun/font/AttributeValues.java index 47acd035e4b99..7e157b95a2297 100644 --- a/src/java.desktop/share/classes/sun/font/AttributeValues.java +++ b/src/java.desktop/share/classes/sun/font/AttributeValues.java @@ -83,6 +83,8 @@ public final class AttributeValues implements Cloneable { private byte bidiEmbedding; // 0 private byte kerning; // 0 private byte ligatures; // 0 + private byte proportionalFigures; // 0 + private byte tabularFigures; // 0 private boolean strikethrough; // false private boolean swapColors; // false @@ -192,6 +194,13 @@ public void setTracking(float f) { public void setLigatures(int f) { this.ligatures = (byte)f; update(ELIGATURES); } + public int getProportionalFigures() { return proportionalFigures; } + public void setProportionalFigures(int f) { + this.proportionalFigures = (byte)f; update(EPROPORTIONAL_FIGURES); } + + public int getTabularFigures() { return tabularFigures; } + public void setTabularFigures(int f) { + this.tabularFigures = (byte)f; update(ETABULAR_FIGURES); } public AffineTransform getBaselineTransform() { return baselineTransform; } public AffineTransform getCharTransform() { return charTransform; } @@ -535,6 +544,8 @@ public String toString() { case EKERNING: b.append(kerning); break; case ELIGATURES: b.append(ligatures); break; case ETRACKING: b.append(tracking); break; + case EPROPORTIONAL_FIGURES: b.append(proportionalFigures); break; + case ETABULAR_FIGURES: b.append(tabularFigures); break; default: throw new InternalError(); } if ((nondefault & ea.mask) == 0) { @@ -593,6 +604,8 @@ private void i_set(EAttribute a, AttributeValues src) { case EKERNING: kerning = src.kerning; break; case ELIGATURES: ligatures = src.ligatures; break; case ETRACKING: tracking = src.tracking; break; + case EPROPORTIONAL_FIGURES: proportionalFigures = src.proportionalFigures; break; + case ETABULAR_FIGURES: tabularFigures = src.tabularFigures; break; default: throw new InternalError(); } } @@ -622,6 +635,8 @@ private boolean i_equals(EAttribute a, AttributeValues src) { case EKERNING: return kerning == src.kerning; case ELIGATURES: return ligatures == src.ligatures; case ETRACKING: return tracking == src.tracking; + case EPROPORTIONAL_FIGURES: return proportionalFigures == src.proportionalFigures; + case ETABULAR_FIGURES: return tabularFigures == src.tabularFigures; default: throw new InternalError(); } } @@ -677,6 +692,8 @@ private void i_set(EAttribute a, Object o) { case EKERNING: kerning = (byte)((Integer)o).intValue(); break; case ELIGATURES: ligatures = (byte)((Integer)o).intValue(); break; case ETRACKING: tracking = ((Number)o).floatValue(); break; + case EPROPORTIONAL_FIGURES: proportionalFigures = (byte) ((Number)o).intValue(); break; + case ETABULAR_FIGURES: tabularFigures = (byte) ((Number)o).intValue(); break; default: throw new InternalError(); } } @@ -717,6 +734,8 @@ private Object i_get(EAttribute a) { case EKERNING: return Integer.valueOf(kerning); case ELIGATURES: return Integer.valueOf(ligatures); case ETRACKING: return Float.valueOf(tracking); + case EPROPORTIONAL_FIGURES: return Integer.valueOf(proportionalFigures); + case ETABULAR_FIGURES: return Integer.valueOf(tabularFigures); default: throw new InternalError(); } } @@ -749,6 +768,8 @@ private boolean i_validate(EAttribute a) { case EKERNING: return kerning >= 0 && kerning <= 1; case ELIGATURES: return ligatures >= 0 && ligatures <= 1; case ETRACKING: return tracking >= -1 && tracking <= 10; + case EPROPORTIONAL_FIGURES: return proportionalFigures >= 0 && proportionalFigures <= 1; + case ETABULAR_FIGURES: return tabularFigures >= 0 && tabularFigures <= 1; default: throw new InternalError("unknown attribute: " + a); } } diff --git a/src/java.desktop/share/classes/sun/font/EAttribute.java b/src/java.desktop/share/classes/sun/font/EAttribute.java index 3a386aa0ced8e..327c4584ee2da 100644 --- a/src/java.desktop/share/classes/sun/font/EAttribute.java +++ b/src/java.desktop/share/classes/sun/font/EAttribute.java @@ -65,7 +65,9 @@ public enum EAttribute { EKERNING(KERNING), ELIGATURES(LIGATURES), ETRACKING(TRACKING), - EBASELINE_TRANSFORM(null); + EBASELINE_TRANSFORM(null), + EPROPORTIONAL_FIGURES(PROPORTIONAL_FIGURES), + ETABULAR_FIGURES(TABULAR_FIGURES); /* package */ final int mask; /* package */ final TextAttribute att; diff --git a/src/java.desktop/share/classes/sun/font/GlyphLayout.java b/src/java.desktop/share/classes/sun/font/GlyphLayout.java index fe2a8bf25998a..2332253a2b13a 100644 --- a/src/java.desktop/share/classes/sun/font/GlyphLayout.java +++ b/src/java.desktop/share/classes/sun/font/GlyphLayout.java @@ -366,6 +366,8 @@ public StandardGlyphVector layout(Font font, FontRenderContext frc, AttributeValues values = ((AttributeMap)font.getAttributes()).getValues(); if (values.getKerning() != 0) _typo_flags |= 0x1; if (values.getLigatures() != 0) _typo_flags |= 0x2; + if (values.getProportionalFigures() != 0) _typo_flags |= 0x4; + if (values.getTabularFigures() != 0) _typo_flags |= 0x8; } _offset = offset; diff --git a/src/java.desktop/share/native/libfontmanager/HBShaper.c b/src/java.desktop/share/native/libfontmanager/HBShaper.c index 1da79bd78ed4a..721018d92a7ac 100644 --- a/src/java.desktop/share/native/libfontmanager/HBShaper.c +++ b/src/java.desktop/share/native/libfontmanager/HBShaper.c @@ -223,6 +223,8 @@ JDKFontInfo* #define TYPO_KERN 0x00000001 #define TYPO_LIGA 0x00000002 +#define TYPO_PNUM 0x00000004 +#define TYPO_TNUM 0x00000008 #define TYPO_RTL 0x80000000 JNIEXPORT jboolean JNICALL Java_sun_font_SunLayoutEngine_shape @@ -255,6 +257,8 @@ JNIEXPORT jboolean JNICALL Java_sun_font_SunLayoutEngine_shape int featureCount = 0; char* kern = (flags & TYPO_KERN) ? "kern" : "-kern"; char* liga = (flags & TYPO_LIGA) ? "liga" : "-liga"; + char* pnum = (flags & TYPO_PNUM) ? "pnum" : "-pnum"; + char* tnum = (flags & TYPO_TNUM) ? "tnum" : "-tnum"; jboolean ret; unsigned int buflen; @@ -293,10 +297,12 @@ JNIEXPORT jboolean JNICALL Java_sun_font_SunLayoutEngine_shape hb_buffer_add_utf16(buffer, chars, len, offset, limit-offset); - features = calloc(2, sizeof(hb_feature_t)); + features = calloc(4, sizeof(hb_feature_t)); if (features) { hb_feature_from_string(kern, -1, &features[featureCount++]); hb_feature_from_string(liga, -1, &features[featureCount++]); + hb_feature_from_string(pnum, -1, &features[featureCount++]); + hb_feature_from_string(tnum, -1, &features[featureCount++]); } hb_shape_full(hbfont, buffer, features, featureCount, 0); diff --git a/src/java.desktop/share/native/libfontmanager/HBShaper_Panama.c b/src/java.desktop/share/native/libfontmanager/HBShaper_Panama.c index f6f4c357c31bc..f27dcd8d8cdf3 100644 --- a/src/java.desktop/share/native/libfontmanager/HBShaper_Panama.c +++ b/src/java.desktop/share/native/libfontmanager/HBShaper_Panama.c @@ -61,6 +61,8 @@ static float euclidianDistance(float a, float b) #define TYPO_KERN 0x00000001 #define TYPO_LIGA 0x00000002 +#define TYPO_PNUM 0x00000004 +#define TYPO_TNUM 0x00000008 #define TYPO_RTL 0x80000000 JDKEXPORT void jdk_hb_shape( @@ -92,6 +94,8 @@ JDKEXPORT void jdk_hb_shape( int featureCount = 0; char* kern = (flags & TYPO_KERN) ? "kern" : "-kern"; char* liga = (flags & TYPO_LIGA) ? "liga" : "-liga"; + char* pnum = (flags & TYPO_PNUM) ? "pnum" : "-pnum"; + char* tnum = (flags & TYPO_TNUM) ? "tnum" : "-tnum"; unsigned int buflen; float devScale = 1.0f; @@ -120,10 +124,12 @@ JDKEXPORT void jdk_hb_shape( int charCount = limit - offset; hb_buffer_add_utf16(buffer, chars, len, offset, charCount); - features = calloc(2, sizeof(hb_feature_t)); + features = calloc(4, sizeof(hb_feature_t)); if (features) { hb_feature_from_string(kern, -1, &features[featureCount++]); hb_feature_from_string(liga, -1, &features[featureCount++]); + hb_feature_from_string(pnum, -1, &features[featureCount++]); + hb_feature_from_string(tnum, -1, &features[featureCount++]); } hb_shape_full(hbfont, buffer, features, featureCount, 0);