aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--AUTHORS1
-rw-r--r--include/core/SkPaint.h47
-rw-r--r--src/core/SkPaint.cpp2
-rw-r--r--src/ports/SkFontHost_FreeType.cpp27
-rwxr-xr-xsrc/ports/SkFontHost_mac.cpp5
-rwxr-xr-xsrc/ports/SkFontHost_win.cpp10
-rw-r--r--src/ports/SkFontHost_win_dw.cpp10
7 files changed, 100 insertions, 2 deletions
diff --git a/AUTHORS b/AUTHORS
index a51e7c6abb..4bef9330ed 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -17,5 +17,6 @@ George Wright <george@mozilla.com>
Google Inc. <*@google.com>
Intel <*@intel.com>
NVIDIA <*@nvidia.com>
+Samsung <*@samsung.com>
The Chromium Authors <*@chromium.org>
Thiago Fransosi Farina <thiago.farina@gmail.com>
diff --git a/include/core/SkPaint.h b/include/core/SkPaint.h
index 48cd573dc4..7d553ec8e0 100644
--- a/include/core/SkPaint.h
+++ b/include/core/SkPaint.h
@@ -731,17 +731,60 @@ public:
void setTextEncoding(TextEncoding encoding);
struct FontMetrics {
+ /** Flags which indicate the confidence level of various metrics.
+ A set flag indicates that the metric may be trusted.
+ */
+ enum FontMetricsFlags {
+ kUnderlineThinknessIsValid_Flag = 1 << 0,
+ kUnderlinePositionIsValid_Flag = 1 << 1,
+ };
+
+ uint32_t fFlags; //!< Bit field to identify which values are unknown
SkScalar fTop; //!< The greatest distance above the baseline for any glyph (will be <= 0)
SkScalar fAscent; //!< The recommended distance above the baseline (will be <= 0)
SkScalar fDescent; //!< The recommended distance below the baseline (will be >= 0)
SkScalar fBottom; //!< The greatest distance below the baseline for any glyph (will be >= 0)
SkScalar fLeading; //!< The recommended distance to add between lines of text (will be >= 0)
- SkScalar fAvgCharWidth; //!< the average charactor width (>= 0)
- SkScalar fMaxCharWidth; //!< the max charactor width (>= 0)
+ SkScalar fAvgCharWidth; //!< the average character width (>= 0)
+ SkScalar fMaxCharWidth; //!< the max character width (>= 0)
SkScalar fXMin; //!< The minimum bounding box x value for all glyphs
SkScalar fXMax; //!< The maximum bounding box x value for all glyphs
SkScalar fXHeight; //!< The height of an 'x' in px, or 0 if no 'x' in face
SkScalar fCapHeight; //!< The cap height (> 0), or 0 if cannot be determined.
+ SkScalar fUnderlineThickness; //!< underline thickness, or 0 if cannot be determined
+
+ /** Underline Position - position of the top of the Underline stroke
+ relative to the baseline, this can have following values
+ - Negative - means underline should be drawn above baseline.
+ - Positive - means below baseline.
+ - Zero - mean underline should be drawn on baseline.
+ */
+ SkScalar fUnderlinePosition; //!< underline position, or 0 if cannot be determined
+
+ /** If the fontmetrics has a valid underlinethickness, return true, and set the
+ thickness param to that value. If it doesn't return false and ignore the
+ thickness param.
+ */
+ bool hasUnderlineThickness(SkScalar* thickness) const {
+ if (SkToBool(fFlags & kUnderlineThinknessIsValid_Flag)) {
+ *thickness = fUnderlineThickness;
+ return true;
+ }
+ return false;
+ }
+
+ /** If the fontmetrics has a valid underlineposition, return true, and set the
+ thickness param to that value. If it doesn't return false and ignore the
+ thickness param.
+ */
+ bool hasUnderlinePosition(SkScalar* position) const {
+ if (SkToBool(fFlags & kUnderlinePositionIsValid_Flag)) {
+ *position = fUnderlinePosition;
+ return true;
+ }
+ return false;
+ }
+
};
/** Return the recommend spacing between lines (which will be
diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp
index 263ba1029c..76fa7349ef 100644
--- a/src/core/SkPaint.cpp
+++ b/src/core/SkPaint.cpp
@@ -1305,6 +1305,8 @@ SkScalar SkPaint::getFontMetrics(FontMetrics* metrics, SkScalar zoom) const {
metrics->fXMin = SkScalarMul(metrics->fXMin, scale);
metrics->fXMax = SkScalarMul(metrics->fXMax, scale);
metrics->fXHeight = SkScalarMul(metrics->fXHeight, scale);
+ metrics->fUnderlineThickness = SkScalarMul(metrics->fUnderlineThickness, scale);
+ metrics->fUnderlinePosition = SkScalarMul(metrics->fUnderlinePosition, scale);
}
return metrics->fDescent - metrics->fAscent + metrics->fLeading;
}
diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp
index cb7ce8028d..fce8259a39 100644
--- a/src/ports/SkFontHost_FreeType.cpp
+++ b/src/ports/SkFontHost_FreeType.cpp
@@ -1390,6 +1390,7 @@ void SkScalerContext_FreeType::generateFontMetrics(SkPaint::FontMetrics* mx,
// pull from format-specific metrics as needed
SkScalar ascent, descent, leading, xmin, xmax, ymin, ymax;
+ SkScalar underlineThickness, underlinePosition;
if (face->face_flags & FT_FACE_FLAG_SCALABLE) { // scalable outline font
ascent = -SkIntToScalar(face->ascender) / upem;
descent = -SkIntToScalar(face->descender) / upem;
@@ -1398,6 +1399,17 @@ void SkScalerContext_FreeType::generateFontMetrics(SkPaint::FontMetrics* mx,
xmax = SkIntToScalar(face->bbox.xMax) / upem;
ymin = -SkIntToScalar(face->bbox.yMin) / upem;
ymax = -SkIntToScalar(face->bbox.yMax) / upem;
+ underlineThickness = SkIntToScalar(face->underline_thickness) / upem;
+ underlinePosition = -SkIntToScalar(face->underline_position) / upem;
+
+ if(mx) {
+ mx->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
+ mx->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
+ }
+ if(my){
+ my->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
+ my->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
+ }
// we may be able to synthesize x_height and cap_height from outline
if (!x_height) {
FT_BBox bbox;
@@ -1422,6 +1434,17 @@ void SkScalerContext_FreeType::generateFontMetrics(SkPaint::FontMetrics* mx,
xmax = SkIntToScalar(face->available_sizes[fStrikeIndex].width) / xppem;
ymin = descent + leading;
ymax = ascent - descent;
+ underlineThickness = 0;
+ underlinePosition = 0;
+
+ if(mx) {
+ mx->fFlags &= ~SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
+ mx->fFlags &= ~SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
+ }
+ if(my){
+ my->fFlags &= ~SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
+ my->fFlags &= ~SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
+ }
} else {
goto ERROR;
}
@@ -1453,6 +1476,8 @@ void SkScalerContext_FreeType::generateFontMetrics(SkPaint::FontMetrics* mx,
mx->fXMax = xmax;
mx->fXHeight = x_height;
mx->fCapHeight = cap_height;
+ mx->fUnderlineThickness = underlineThickness;
+ mx->fUnderlinePosition = underlinePosition;
}
if (my) {
my->fTop = ymax * myy;
@@ -1465,6 +1490,8 @@ void SkScalerContext_FreeType::generateFontMetrics(SkPaint::FontMetrics* mx,
my->fXMax = xmax;
my->fXHeight = x_height;
my->fCapHeight = cap_height;
+ my->fUnderlineThickness = underlineThickness;
+ my->fUnderlinePosition = underlinePosition;
}
}
diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp
index ac0e365e2e..26d30d726a 100755
--- a/src/ports/SkFontHost_mac.cpp
+++ b/src/ports/SkFontHost_mac.cpp
@@ -1379,6 +1379,11 @@ void SkScalerContext_Mac::generateFontMetrics(SkPaint::FontMetrics* mx,
theMetrics.fXMin = CGToScalar( CGRectGetMinX_inline(theBounds));
theMetrics.fXMax = CGToScalar( CGRectGetMaxX_inline(theBounds));
theMetrics.fXHeight = CGToScalar( CTFontGetXHeight(fCTFont));
+ theMetrics.fUnderlineThickness = CGToScalar( CTFontGetUnderlineThickness(fCTFont));
+ theMetrics.fUnderlinePosition = -CGToScalar( CTFontGetUnderlinePosition(fCTFont));
+
+ theMetrics.fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
+ theMetrics.fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
if (mx != NULL) {
*mx = theMetrics;
diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp
index 4ca0fb9181..9dc720a643 100755
--- a/src/ports/SkFontHost_win.cpp
+++ b/src/ports/SkFontHost_win.cpp
@@ -1061,6 +1061,11 @@ void SkScalerContext_GDI::generateFontMetrics(SkPaint::FontMetrics* mx, SkPaint:
mx->fDescent = SkIntToScalar(-otm.otmDescent);
mx->fBottom = SkIntToScalar(otm.otmrcFontBox.right);
mx->fLeading = SkIntToScalar(otm.otmLineGap);
+ mx->fUnderlineThickness = SkIntToScalar(otm.otmsUnderscoreSize);
+ mx->fUnderlinePosition = -SkIntToScalar(otm.otmsUnderscorePosition);
+
+ mx->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
+ mx->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
}
if (my) {
@@ -1074,6 +1079,11 @@ void SkScalerContext_GDI::generateFontMetrics(SkPaint::FontMetrics* mx, SkPaint:
my->fMaxCharWidth = SkIntToScalar(otm.otmTextMetrics.tmMaxCharWidth);
my->fXMin = SkIntToScalar(otm.otmrcFontBox.left);
my->fXMax = SkIntToScalar(otm.otmrcFontBox.right);
+ my->fUnderlineThickness = SkIntToScalar(otm.otmsUnderscoreSize);
+ my->fUnderlinePosition = -SkIntToScalar(otm.otmsUnderscorePosition);
+
+ my->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
+ my->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
#endif
my->fXHeight = SkIntToScalar(otm.otmsXHeight);
diff --git a/src/ports/SkFontHost_win_dw.cpp b/src/ports/SkFontHost_win_dw.cpp
index ce5e49b358..b80154aa61 100644
--- a/src/ports/SkFontHost_win_dw.cpp
+++ b/src/ports/SkFontHost_win_dw.cpp
@@ -874,6 +874,11 @@ void SkScalerContext_DW::generateFontMetrics(SkPaint::FontMetrics* mx,
mx->fBottom = mx->fDescent;
mx->fLeading = fRec.fTextSize * SkIntToScalar(dwfm.lineGap) / upem;
mx->fXHeight = fRec.fTextSize * SkIntToScalar(dwfm.xHeight) / upem;
+ mx->fUnderlineThickness = fRec.fTextSize * SkIntToScalar(dwfm.underlinePosition) / upem;
+ mx->fUnderlinePosition = -(fRec.fTextSize * SkIntToScalar(dwfm.underlineThickness) / upem);
+
+ mx->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
+ mx->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
}
if (my) {
@@ -883,6 +888,11 @@ void SkScalerContext_DW::generateFontMetrics(SkPaint::FontMetrics* mx,
my->fBottom = my->fDescent;
my->fLeading = fRec.fTextSize * SkIntToScalar(dwfm.lineGap) / upem;
my->fXHeight = fRec.fTextSize * SkIntToScalar(dwfm.xHeight) / upem;
+ my->fUnderlineThickness = fRec.fTextSize * SkIntToScalar(dwfm.underlinePosition) / upem;
+ my->fUnderlinePosition = -(fRec.fTextSize * SkIntToScalar(dwfm.underlineThickness) / upem);
+
+ my->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag;
+ my->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag;
}
}