summaryrefslogtreecommitdiffstats
path: root/src/libnrtype
diff options
context:
space:
mode:
authorTavmjong Bah <tavmjong@free.fr>2015-11-13 14:35:25 +0000
committertavmjong-free <tavmjong@free.fr>2015-11-13 14:35:25 +0000
commitd136162e0abe6b045ac791b8eb0e16ee51b3f7cc (patch)
tree59ff9fb27b0636943fd27ff06a4d8d9923da6281 /src/libnrtype
parent'direction' is an inherited property, remove 'set' requirement. (diff)
downloadinkscape-d136162e0abe6b045ac791b8eb0e16ee51b3f7cc.tar.gz
inkscape-d136162e0abe6b045ac791b8eb0e16ee51b3f7cc.zip
Replace leading by more useful x-height. Use OS/2 font metrics when available.
Use otmMacAscent/otmMacDescent rather than otmAscent/otmDescent. Actually both should be available as they have different purposes... (bzr r14430.1.5)
Diffstat (limited to 'src/libnrtype')
-rw-r--r--src/libnrtype/FontInstance.cpp66
-rw-r--r--src/libnrtype/Layout-TNG-Compute.cpp6
-rw-r--r--src/libnrtype/Layout-TNG.h9
-rw-r--r--src/libnrtype/TextWrapper.cpp4
-rw-r--r--src/libnrtype/one-box.h2
5 files changed, 66 insertions, 21 deletions
diff --git a/src/libnrtype/FontInstance.cpp b/src/libnrtype/FontInstance.cpp
index 6b2e030d1..5853d5217 100644
--- a/src/libnrtype/FontInstance.cpp
+++ b/src/libnrtype/FontInstance.cpp
@@ -21,6 +21,7 @@
#include FT_BBOX_H
#include FT_TRUETYPE_TAGS_H
#include FT_TRUETYPE_TABLES_H
+#include FT_GLYPH_H
#include <pango/pangoft2.h>
#include <2geom/pathvector.h>
#include <2geom/path-sink.h>
@@ -507,7 +508,7 @@ void font_instance::LoadGlyph(int glyph_id)
}
}
-bool font_instance::FontMetrics(double &ascent,double &descent,double &leading)
+bool font_instance::FontMetrics(double &ascent,double &descent,double &xheight)
{
if ( pFont == NULL ) {
return false;
@@ -516,34 +517,77 @@ bool font_instance::FontMetrics(double &ascent,double &descent,double &leading)
if ( theFace == NULL ) {
return false;
}
+
+ // CSS2 recommends using the OS/2 values sTypoAscender and sTypoDescender
+ // for the ascender and descender values:
+ // http://www.w3.org/TR/CSS2/visudet.html#sTypoAscender
+ // The typographic ascender and descender are taken from the
+ // otmMacAscent and otmMacDescent values:
+ // http://microsoft.public.win32.programmer.gdi.narkive.com/LV6k4BDh/msdn-documentation-outlinetextmetrics-clarification
+ // The otmAscent and otmDescent values are the maxiumum ascent and maxiumum
+ // descent of all the glyphs in a font.
+
#ifdef USE_PANGO_WIN32
OUTLINETEXTMETRIC otm;
if ( !GetOutlineTextMetrics(parent->hScreenDC,sizeof(otm),&otm) ) {
return false;
}
+
double scale=1.0/parent->fontSize;
- ascent=fabs(otm.otmAscent*scale);
- descent=fabs(otm.otmDescent*scale);
- leading=fabs(otm.otmLineGap*scale);
+ ascent=fabs(otm.otmMacAscent*scale);
+ descent=fabs(otm.otmMacDescent*scale);
+ xheight=fabs(otm.otmXHeight*scale);
+ // May not be necessary... but if OS/2 table is missing or not version 2 or higher,
+ // xheight might be set to 0.
+ if( xheight = 0.0 ) xheight = ascent/2.0;
//otmSubscriptSize, otmSubscriptOffset, otmSuperscriptSize, otmSuperscriptOffset,
#else
if ( theFace->units_per_EM == 0 ) {
return false; // bitmap font
}
- ascent=fabs(((double)theFace->ascender)/((double)theFace->units_per_EM));
- descent=fabs(((double)theFace->descender)/((double)theFace->units_per_EM));
- leading=fabs(((double)theFace->height)/((double)theFace->units_per_EM));
- leading-=ascent+descent;
+
+ TT_OS2* os2 = (TT_OS2*)FT_Get_Sfnt_Table( theFace, FT_SFNT_OS2 );
+ if( os2 ) {
+ ascent =fabs(((double)os2->sTypoAscender)/((double)theFace->units_per_EM));
+ descent=fabs(((double)os2->sTypoDescender)/((double)theFace->units_per_EM));
+ } else {
+ ascent =fabs(((double)theFace->ascender)/((double)theFace->units_per_EM));
+ descent=fabs(((double)theFace->descender)/((double)theFace->units_per_EM));
+ }
+
+ // We must find x-height ourselves! First try OS/2 table.
+ if( os2 && os2->version >= 0x0002 && os2->version != 0xffffu ) {
+ // Only os/2 version 2 and above have sxHeight, 0xffff marks "old Mac fonts" without table
+ xheight=fabs(((double)os2->sxHeight)/((double)theFace->units_per_EM));
+ } else {
+ // Measure 'x' height in font. Recommended option by XSL standard if no sxHeight.
+ FT_UInt index = FT_Get_Char_Index( theFace, 'x' );
+ if( index != 0 ) {
+ FT_Load_Glyph( theFace, index, FT_LOAD_NO_SCALE );
+ xheight = (fabs)(((double)theFace->glyph->metrics.height/(double)theFace->units_per_EM));
+ } else {
+ // No 'x' in font!
+ xheight = ascent/2.0;
+ }
+ }
#endif
- // CSS dictates em size is ascent + descent
+ // CSS dictates em size is ascent + descent.... but this doesn't seem to be used in practice.
+ // The em size is what the font reports...
double em = ascent + descent;
if( em <= 0 ) {
- return false; // Pathological
+ return false; // Pathological
}
ascent /= em;
descent /= em;
- leading /= em;
+ xheight /= em;
+
+ // gchar* font_name = pango_font_description_to_string( descr );
+ // std::cout << "Font: " << (font_name ? font_name : ("Null")) << std::endl;
+ // g_free( font_name );
+ // std::cout << " ascent: " << ascent << " descent: " << descent
+ // << " x-height: " << xheight << "\n" << std::endl;
+
return true;
}
diff --git a/src/libnrtype/Layout-TNG-Compute.cpp b/src/libnrtype/Layout-TNG-Compute.cpp
index 8f7f6bca0..6b5697b10 100644
--- a/src/libnrtype/Layout-TNG-Compute.cpp
+++ b/src/libnrtype/Layout-TNG-Compute.cpp
@@ -1121,7 +1121,7 @@ void Layout::Calculator::_computeFontLineHeight(font_instance *font, double font
*line_height_multiplier = 1.0;
}
else {
- font->FontMetrics(font_metrics->ascent, font_metrics->descent, font_metrics->leading);
+ font->FontMetrics(font_metrics->ascent, font_metrics->descent, font_metrics->xheight);
}
*font_metrics *= font_size;
@@ -1819,13 +1819,13 @@ void Layout::_calculateCursorShapeForEmpty()
FontMetrics line_height;
if (font) {
const_cast<font_instance*>(font)->FontSlope(caret_slope_run, caret_slope_rise);
- font->FontMetrics(line_height.ascent, line_height.descent, line_height.leading);
+ font->FontMetrics(line_height.ascent, line_height.descent, line_height.xheight);
line_height *= font_size;
font->Unref();
} else {
line_height.ascent = font_size * 0.85; // random guesses
line_height.descent = font_size * 0.15;
- line_height.leading = 0.0;
+ line_height.xheight = 0.0;
}
double caret_slope = atan2(caret_slope_run, caret_slope_rise);
_empty_cursor_shape.height = font_size / cos(caret_slope);
diff --git a/src/libnrtype/Layout-TNG.h b/src/libnrtype/Layout-TNG.h
index 6875fa14a..c2895e05f 100644
--- a/src/libnrtype/Layout-TNG.h
+++ b/src/libnrtype/Layout-TNG.h
@@ -610,7 +610,7 @@ public:
/**
* Keep track of font metrics. Two use cases:
- * 1. Keep track of ascent and descent of an individual font.
+ * 1. Keep track of ascent, descent, and x-height of an individual font.
* 2. Keep track of effective ascent and descent that includes half-leading.
*
* Note: Leading refers to the "external" leading which is added (subtracted) due to
@@ -626,16 +626,16 @@ public:
double ascent;
double descent;
- double leading; // Not used... to be removed (requires change to font->FontMetrics()
+ double xheight;
// CSS 2.1 dictates that font-size is based on em-size which is defined as ascent + descent
inline double emSize() const {return ascent + descent;}
// Alternatively name function for use 2.
inline double lineSize() const { return ascent + descent; }
- inline void setZero() {ascent = descent = 0.0;}
+ inline void setZero() {ascent = descent = xheight = 0.0;}
// For scaling for 'font-size'.
- inline FontMetrics& operator*=(double x) {ascent *= x; descent *= x; return *this;}
+ inline FontMetrics& operator*=(double x) {ascent *= x; descent *= x; xheight *= x; return *this;}
/// Save the larger values of ascent and descent between this and other. Needed for laying
/// out a line with mixed font-sizes, fonts, or line spacings.
@@ -646,6 +646,7 @@ public:
inline double getAscent() const {return ascent; }
inline double getDescent() const {return descent; }
+ inline double getXheight() const {return xheight; }
};
/// see _enum_converter()
diff --git a/src/libnrtype/TextWrapper.cpp b/src/libnrtype/TextWrapper.cpp
index 380e9ba3f..124f3f7b4 100644
--- a/src/libnrtype/TextWrapper.cpp
+++ b/src/libnrtype/TextWrapper.cpp
@@ -862,7 +862,7 @@ void text_wrapper::MeasureBoxes(void)
for (int i = 0; i < nbBox; i++) {
boxes[i].ascent = 0;
boxes[i].descent = 0;
- boxes[i].leading = 0;
+ boxes[i].xheight = 0;
boxes[i].width = 0;
PangoFont *curPF = glyph_text[boxes[i].g_st].font;
@@ -870,7 +870,7 @@ void text_wrapper::MeasureBoxes(void)
PangoFontDescription *pfd = pango_font_describe(curPF);
font_instance *curF = f_src->Face(pfd);
if ( curF ) {
- curF->FontMetrics(boxes[i].ascent, boxes[i].descent, boxes[i].leading);
+ curF->FontMetrics(boxes[i].ascent, boxes[i].descent, boxes[i].xheight);
curF->Unref();
}
pango_font_description_free(pfd);
diff --git a/src/libnrtype/one-box.h b/src/libnrtype/one-box.h
index c868cf23f..c3b36a3ce 100644
--- a/src/libnrtype/one-box.h
+++ b/src/libnrtype/one-box.h
@@ -9,7 +9,7 @@
// this time for sp-typeset
struct one_box {
int g_st, g_en; ///< First and last glyph of this word.
- double ascent, descent, leading;
+ double ascent, descent, xheight;
double width;
bool word_start, word_end;
};