diff options
| author | Tavmjong Bah <tavmjong@free.fr> | 2015-11-13 14:35:25 +0000 |
|---|---|---|
| committer | tavmjong-free <tavmjong@free.fr> | 2015-11-13 14:35:25 +0000 |
| commit | d136162e0abe6b045ac791b8eb0e16ee51b3f7cc (patch) | |
| tree | 59ff9fb27b0636943fd27ff06a4d8d9923da6281 /src/libnrtype | |
| parent | 'direction' is an inherited property, remove 'set' requirement. (diff) | |
| download | inkscape-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.cpp | 66 | ||||
| -rw-r--r-- | src/libnrtype/Layout-TNG-Compute.cpp | 6 | ||||
| -rw-r--r-- | src/libnrtype/Layout-TNG.h | 9 | ||||
| -rw-r--r-- | src/libnrtype/TextWrapper.cpp | 4 | ||||
| -rw-r--r-- | src/libnrtype/one-box.h | 2 |
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; }; |
