From 2abe0bb681044d972e171189395a2afdbc39bf28 Mon Sep 17 00:00:00 2001 From: Khaled Hosny Date: Tue, 15 Aug 2017 22:39:32 +0200 Subject: Fix inverted y sign for glyph positioning This is causing vertical glyph positioning to move in the wrong direction e.g. marks go below base glyph instead of above. Seems to be a regression introduced in: commit 83dac189ff21c59be9b4f912e0d0e9690e710a4d Author: Tavmjong Bah Date: Tue Nov 3 13:19:36 2015 +0100 Rearrange code to make handling of baseline clearer. (bzr r14430.1.3) --- src/libnrtype/Layout-TNG-Compute.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG-Compute.cpp b/src/libnrtype/Layout-TNG-Compute.cpp index 63364ab34..5d0c5c3ce 100644 --- a/src/libnrtype/Layout-TNG-Compute.cpp +++ b/src/libnrtype/Layout-TNG-Compute.cpp @@ -767,7 +767,7 @@ void Layout::Calculator::_outputLine(ParagraphInfo const ¶, if( dominant_baseline == SP_CSS_BASELINE_AUTO ) dominant_baseline = SP_CSS_BASELINE_ALPHABETIC; } - new_glyph.y += delta_y; + new_glyph.y -= delta_y; // TODO: Should also check 'glyph_orientation_vertical' if 'text-orientation' is unset... if( new_span.text_orientation == SP_CSS_TEXT_ORIENTATION_SIDEWAYS || @@ -801,7 +801,7 @@ void Layout::Calculator::_outputLine(ParagraphInfo const ¶, if( dominant_baseline == SP_CSS_BASELINE_AUTO ) dominant_baseline = SP_CSS_BASELINE_ALPHABETIC; - new_glyph.y -= delta_y; + new_glyph.y += delta_y; new_glyph.y += new_span.font_size * para.pango_items[unbroken_span.pango_item_index].font->GetBaselines()[ dominant_baseline ]; new_glyph.width = unbroken_span_glyph_info->geometry.width * font_size_multiplier; -- cgit v1.2.3 From f7e6b3725686becd2b8d034cc572417e5a272cba Mon Sep 17 00:00:00 2001 From: Khaled Hosny Date: Tue, 15 Aug 2017 22:41:53 +0200 Subject: Fix RTL glyph widths in vertical orientation The vertical branch seems to be broken, removing it makes RTL text in vertical orientation work again. --- src/libnrtype/Layout-TNG-Compute.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG-Compute.cpp b/src/libnrtype/Layout-TNG-Compute.cpp index 5d0c5c3ce..f812f0c41 100644 --- a/src/libnrtype/Layout-TNG-Compute.cpp +++ b/src/libnrtype/Layout-TNG-Compute.cpp @@ -818,12 +818,7 @@ void Layout::Calculator::_outputLine(ParagraphInfo const ¶, for (unsigned rtl_index = glyph_index; rtl_index < it_span->end_glyph_index ; rtl_index++) { if (unbroken_span.glyph_string->glyphs[rtl_index].attr.is_cluster_start && rtl_index != glyph_index) break; - if (_block_progression == LEFT_TO_RIGHT || _block_progression == RIGHT_TO_LEFT) - // Vertical text - cluster_width += new_span.font_size * para.pango_items[unbroken_span.pango_item_index].font->Advance(unbroken_span.glyph_string->glyphs[rtl_index].glyph, true); - else - // Horizontal text - cluster_width += font_size_multiplier * unbroken_span.glyph_string->glyphs[rtl_index].geometry.width; + cluster_width += font_size_multiplier * unbroken_span.glyph_string->glyphs[rtl_index].geometry.width; } new_glyph.x -= cluster_width; } -- cgit v1.2.3 From b0e00d7b7fd82a4c4abcd28b467fd83ed6ee6164 Mon Sep 17 00:00:00 2001 From: Khaled Hosny Date: Fri, 18 Aug 2017 00:45:37 +0200 Subject: Fix vertical RTL text with upright orientation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When orientation is upright we don’t want Pango to use the natural gravity of the text (that would be the mixed orientation). This also changes the positioning of combining marks in such case. It is still wrong, however, but it matches Pango output now. --- src/libnrtype/Layout-TNG-Compute.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG-Compute.cpp b/src/libnrtype/Layout-TNG-Compute.cpp index f812f0c41..504314046 100644 --- a/src/libnrtype/Layout-TNG-Compute.cpp +++ b/src/libnrtype/Layout-TNG-Compute.cpp @@ -1746,6 +1746,10 @@ bool Layout::Calculator::calculate() if( _block_progression == RIGHT_TO_LEFT || _block_progression == LEFT_TO_RIGHT ) { // Vertical text, CJK pango_context_set_base_gravity(_pango_context, PANGO_GRAVITY_EAST); + + if( _flow._blockTextOrientation() != SP_CSS_TEXT_ORIENTATION_MIXED ) { + pango_context_set_gravity_hint(_pango_context, PANGO_GRAVITY_HINT_STRONG); + } } else { // Horizontal text pango_context_set_base_gravity(_pango_context, PANGO_GRAVITY_AUTO); -- cgit v1.2.3 From cdb439b810e67df7ffe090848a072fe1f5c44e32 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 6 Sep 2017 11:14:29 +0200 Subject: Minor code cleanup. --- src/libnrtype/Layout-TNG-Compute.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG-Compute.cpp b/src/libnrtype/Layout-TNG-Compute.cpp index 504314046..d9ab8694b 100644 --- a/src/libnrtype/Layout-TNG-Compute.cpp +++ b/src/libnrtype/Layout-TNG-Compute.cpp @@ -698,6 +698,7 @@ void Layout::Calculator::_outputLine(ParagraphInfo const ¶, if (_flow._input_stream[unbroken_span.input_index]->Type() == TEXT_SOURCE) { // the span is set up, push the glyphs and chars + InputStreamTextSource const *text_source = static_cast(_flow._input_stream[unbroken_span.input_index]); Glib::ustring::const_iterator iter_source_text = Glib::ustring::const_iterator(unbroken_span.input_stream_first_character.base() + it_span->start.char_byte) ; unsigned char_index_in_unbroken_span = it_span->start.char_index; @@ -708,9 +709,9 @@ void Layout::Calculator::_outputLine(ParagraphInfo const ¶, for (unsigned glyph_index = it_span->start_glyph_index ; glyph_index < it_span->end_glyph_index ; glyph_index++) { unsigned char_byte = iter_source_text.base() - unbroken_span.input_stream_first_character.base(); - int newcluster = 0; - if (unbroken_span.glyph_string->glyphs[glyph_index].attr.is_cluster_start){ - newcluster = 1; + bool newcluster = false; + if (unbroken_span.glyph_string->glyphs[glyph_index].attr.is_cluster_start) { + newcluster = true; x_in_span = x_in_span_last; } @@ -774,7 +775,7 @@ void Layout::Calculator::_outputLine(ParagraphInfo const ¶, (new_span.text_orientation == SP_CSS_TEXT_ORIENTATION_MIXED && para.pango_items[unbroken_span.pango_item_index].item->analysis.gravity == 0) ) { - // Sideways orientation (Latin characters, CJK punctuation), 90deg rotation done at output stage. zzzzzzz + // Sideways orientation (Latin characters, CJK punctuation), 90deg rotation done at output stage. new_glyph.orientation = ORIENTATION_SIDEWAYS; new_glyph.y -= new_span.font_size * para.pango_items[unbroken_span.pango_item_index].font->GetBaselines()[ dominant_baseline ]; @@ -826,8 +827,9 @@ void Layout::Calculator::_outputLine(ParagraphInfo const ¶, // create the Layout::Character(s) double advance_width = new_glyph.width; - if (newcluster){ - newcluster = 0; + if (newcluster) { + newcluster = false; + // find where the text ends for this log_cluster end_byte = it_span->start.iter_span->text_bytes; // Upper limit for(int next_glyph_index = glyph_index+1; next_glyph_index < unbroken_span.glyph_string->num_glyphs; next_glyph_index++){ @@ -836,6 +838,7 @@ void Layout::Calculator::_outputLine(ParagraphInfo const ¶, break; } } + // Figure out how many glyphs and characters are in the log_cluster. log_cluster_size_glyphs = 0; log_cluster_size_chars = 0; @@ -843,6 +846,7 @@ void Layout::Calculator::_outputLine(ParagraphInfo const ¶, if(unbroken_span.glyph_string->log_clusters[glyph_index ] != unbroken_span.glyph_string->log_clusters[glyph_index + log_cluster_size_glyphs])break; } + Glib::ustring::const_iterator lclist = iter_source_text; unsigned lcb = char_byte; while(lcb < end_byte){ @@ -851,6 +855,7 @@ void Layout::Calculator::_outputLine(ParagraphInfo const ¶, lcb = lclist.base() - unbroken_span.input_stream_first_character.base(); } } + while (char_byte < end_byte) { /* Hack to survive ligatures: in log_cluster keep the number of available chars >= number of glyphs remaining. When there are no ligatures these two sizes are always the same. -- cgit v1.2.3 From bfc70139347781252b7d6860cde5722ed9d5a487 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 7 Sep 2017 18:00:25 +0200 Subject: Fix infinite loop when rendering text inside a shape under very special conditions. (When a line does not fit due to its height but when refitted with a larger height it is broken into multiple chunks and no text fits into the first chunk.) Fixes bug #1715442. --- src/libnrtype/Layout-TNG-Compute.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG-Compute.cpp b/src/libnrtype/Layout-TNG-Compute.cpp index d9ab8694b..1bc035856 100644 --- a/src/libnrtype/Layout-TNG-Compute.cpp +++ b/src/libnrtype/Layout-TNG-Compute.cpp @@ -253,8 +253,7 @@ class Layout::Calculator UnbrokenSpanPosition const &start_span_pos, ScanlineMaker::ScanRun const &scan_run, std::vector *chunk_info, - FontMetrics *line_height, - FontMetrics const *strut_height) const; + FontMetrics *line_height) const; bool _measureUnbrokenSpan(ParagraphInfo const ¶, BrokenSpan *span, @@ -1472,8 +1471,8 @@ bool Layout::Calculator::_findChunksForLine(ParagraphInfo const ¶, TRACE((" initial line_box_height (em size): %f\n", line_box_height->emSize() )); UnbrokenSpanPosition span_pos; + static int trys = 0; for( ; ; ) { - // Get regions where one can place one line of text (can be more than one, if filling a // donut for example). std::vector scan_runs; @@ -1495,10 +1494,9 @@ bool Layout::Calculator::_findChunksForLine(ParagraphInfo const ¶, unsigned scan_run_index; span_pos = *start_span_pos; for (scan_run_index = 0 ; scan_run_index < scan_runs.size() ; scan_run_index++) { - // Returns false if some text in line requires a taller line_box_height. // (We try again with a larger line_box_height.) - if (!_buildChunksInScanRun(para, span_pos, scan_runs[scan_run_index], chunk_info, line_box_height, strut_height)) { + if (!_buildChunksInScanRun(para, span_pos, scan_runs[scan_run_index], chunk_info, line_box_height)) { break; } @@ -1534,11 +1532,12 @@ bool Layout::Calculator::_buildChunksInScanRun(ParagraphInfo const ¶, UnbrokenSpanPosition const &start_span_pos, ScanlineMaker::ScanRun const &scan_run, std::vector *chunk_info, - FontMetrics *line_height, - FontMetrics const *strut_height) const + FontMetrics *line_height) const { TRACE((" begin _buildChunksInScanRun: chunks: %lu, em size: %f\n", chunk_info->size(), line_height->emSize() )); + FontMetrics line_height_saved = *line_height; // Store for recalculating line height if chunks are backed out + ChunkInfo new_chunk; new_chunk.text_width = 0.0; new_chunk.whitespace_count = 0; @@ -1647,7 +1646,7 @@ bool Layout::Calculator::_buildChunksInScanRun(ParagraphInfo const ¶, } // Recalculate line_box_height after backing out chunks - *line_height = *strut_height; + *line_height = line_height_saved; for (std::vector::const_iterator it_chunk = chunk_info->begin() ; it_chunk != chunk_info->end() ; it_chunk++) { for (std::vector::const_iterator it_span = it_chunk->broken_spans.begin() ; it_span != it_chunk->broken_spans.end() ; it_span++) { FontMetrics span_height = it_span->start.iter_span->line_height; -- cgit v1.2.3 From 4610a0f7f704afd0daf15350b40e0851881a2c78 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 13 Sep 2017 10:40:43 +0200 Subject: Improve rendering of vertical text with non-spacing marks in upright orientation. --- src/libnrtype/Layout-TNG-Compute.cpp | 61 +++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 19 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG-Compute.cpp b/src/libnrtype/Layout-TNG-Compute.cpp index 1bc035856..38c3c48c4 100644 --- a/src/libnrtype/Layout-TNG-Compute.cpp +++ b/src/libnrtype/Layout-TNG-Compute.cpp @@ -398,17 +398,28 @@ bool Layout::Calculator::_measureUnbrokenSpan(ParagraphInfo const ¶, double char_width = 0.0; while (span->end_glyph_index < (unsigned)span->end.iter_span->glyph_string->num_glyphs && span->end.iter_span->glyph_string->log_clusters[span->end_glyph_index] <= (int)span->end.char_byte) { + + PangoGlyphInfo *info = &(span->end.iter_span->glyph_string->glyphs[span->end_glyph_index]); + // double glyph_width = font_size_multiplier * info->geometry.width; + // double glyph_x_offset = font_size_multiplier * info->geometry.x_offset; + // double glyph_y_offset = font_size_multiplier * info->geometry.y_offset; + // std::cout << " glyph: " << info->glyph << " width: " << glyph_width << " x_offset: " << glyph_x_offset << " y_offset: " << glyph_y_offset << std::endl; + if (_block_progression == LEFT_TO_RIGHT || _block_progression == RIGHT_TO_LEFT) { // Vertical text if( text_source->style->text_orientation.computed == SP_CSS_TEXT_ORIENTATION_SIDEWAYS || (text_source->style->text_orientation.computed == SP_CSS_TEXT_ORIENTATION_MIXED && - para.pango_items[span->end.iter_span->pango_item_index].item->analysis.gravity == 0) ) { + para.pango_items[span->end.iter_span->pango_item_index].item->analysis.gravity == PANGO_GRAVITY_SOUTH) ) { // Sideways orientation - char_width += span->start.iter_span->font_size * para.pango_items[span->end.iter_span->pango_item_index].font->Advance(span->end.iter_span->glyph_string->glyphs[span->end_glyph_index].glyph, false); + char_width += span->start.iter_span->font_size * para.pango_items[span->end.iter_span->pango_item_index].font->Advance(info->glyph, false); } else { // Upright orientation - char_width += span->start.iter_span->font_size * para.pango_items[span->end.iter_span->pango_item_index].font->Advance(span->end.iter_span->glyph_string->glyphs[span->end_glyph_index].glyph, true); + guint32 c = *Glib::ustring::const_iterator(span->end.iter_span->input_stream_first_character.base() + span->end.char_byte); + if (g_unichar_type (c) != G_UNICODE_NON_SPACING_MARK) { + // Non-spacing marks should not contribute to width. Fonts may not report the correct advance, especially if the 'vmtx' table is missing. + char_width += span->start.iter_span->font_size * para.pango_items[span->end.iter_span->pango_item_index].font->Advance(info->glyph, true); + } } } else { // Horizontal text @@ -416,6 +427,7 @@ bool Layout::Calculator::_measureUnbrokenSpan(ParagraphInfo const ¶, } span->end_glyph_index++; } + if (char_attributes.is_cursor_position) char_width += text_source->style->letter_spacing.computed * _flow.getTextLengthMultiplierDue(); if (char_attributes.is_white) @@ -434,6 +446,7 @@ bool Layout::Calculator::_measureUnbrokenSpan(ParagraphInfo const ¶, if (is_soft_hyphen) soft_hyphen_glyph_width = char_width; + // Go to next character (resets end.char_byte to zero if at end) span->end.increment(); // Width should not include letter_spacing (or word_spacing) after last letter at end of line. @@ -662,8 +675,8 @@ void Layout::Calculator::_outputLine(ParagraphInfo const ¶, new_span.block_progression = _block_progression; new_span.text_orientation = unbroken_span.text_orientation; if ((_flow._input_stream[unbroken_span.input_index]->Type() == TEXT_SOURCE) && (new_span.font = para.pango_items[unbroken_span.pango_item_index].font)) - { - new_span.font->Ref(); + { + new_span.font->Ref(); new_span.font_size = unbroken_span.font_size; new_span.direction = para.pango_items[unbroken_span.pango_item_index].item->analysis.level & 1 ? RIGHT_TO_LEFT : LEFT_TO_RIGHT; new_span.input_stream_first_character = Glib::ustring::const_iterator(unbroken_span.input_stream_first_character.base() + it_span->start.char_byte); @@ -750,10 +763,12 @@ void Layout::Calculator::_outputLine(ParagraphInfo const ¶, new_glyph.vertical_scale = 1.0; // Position glyph -------------------- - new_glyph.x = current_x + unbroken_span_glyph_info->geometry.x_offset * font_size_multiplier; + new_glyph.x = current_x; new_glyph.y =_y_offset; - // y-coordinate is flipped between vertical and horizontal text... delta_y is common offset but applied with opposite sign + // y-coordinate is flipped between vertical and horizontal text... + // delta_y is common offset but applied with opposite sign + double delta_x = unbroken_span_glyph_info->geometry.x_offset * font_size_multiplier; double delta_y = unbroken_span_glyph_info->geometry.y_offset * font_size_multiplier + unbroken_span.baseline_shift; SPCSSBaseline dominant_baseline = _flow._blockBaseline(); @@ -767,41 +782,50 @@ void Layout::Calculator::_outputLine(ParagraphInfo const ¶, if( dominant_baseline == SP_CSS_BASELINE_AUTO ) dominant_baseline = SP_CSS_BASELINE_ALPHABETIC; } - new_glyph.y -= delta_y; - // TODO: Should also check 'glyph_orientation_vertical' if 'text-orientation' is unset... if( new_span.text_orientation == SP_CSS_TEXT_ORIENTATION_SIDEWAYS || (new_span.text_orientation == SP_CSS_TEXT_ORIENTATION_MIXED && - para.pango_items[unbroken_span.pango_item_index].item->analysis.gravity == 0) ) { + para.pango_items[unbroken_span.pango_item_index].item->analysis.gravity == PANGO_GRAVITY_SOUTH) ) { // Sideways orientation (Latin characters, CJK punctuation), 90deg rotation done at output stage. new_glyph.orientation = ORIENTATION_SIDEWAYS; - new_glyph.y -= new_span.font_size * para.pango_items[unbroken_span.pango_item_index].font->GetBaselines()[ dominant_baseline ]; + new_glyph.x += delta_x; + new_glyph.y -= delta_y; + + new_glyph.y -= new_span.font_size * para.pango_items[unbroken_span.pango_item_index].font->GetBaselines()[ dominant_baseline ]; new_glyph.width = new_span.font_size * para.pango_items[unbroken_span.pango_item_index].font->Advance(unbroken_span_glyph_info->glyph, false); } else { // Upright orientation - new_glyph.x += new_span.line_height.ascent; + new_glyph.x += delta_x; + new_glyph.y -= delta_y; - // Glyph reference point is center (shift: left edge to center glyph) - new_glyph.y -= unbroken_span_glyph_info->geometry.width * 0.5 * font_size_multiplier; + // Adjust for alignment point (top of em box, horizontal center). + new_glyph.x += new_span.line_height.ascent; new_glyph.y -= new_span.font_size * (para.pango_items[unbroken_span.pango_item_index].font->GetBaselines()[ dominant_baseline ] - para.pango_items[unbroken_span.pango_item_index].font->GetBaselines()[ SP_CSS_BASELINE_CENTRAL ] ); - new_glyph.width = new_span.font_size * para.pango_items[unbroken_span.pango_item_index].font->Advance(unbroken_span_glyph_info->glyph, true); - if( new_glyph.width == 0 ) { - new_glyph.width = unbroken_span_glyph_info->geometry.width * font_size_multiplier; + static double shift_y = 0; // Save to use with non_spacing marks (should be shifted the same amount as previous glyph). + if (g_unichar_type (*iter_source_text) == G_UNICODE_NON_SPACING_MARK) { + new_glyph.width = 0; + new_glyph.x += new_span.font_size; // Hack! + } else { + // Glyph reference point is center (shift: left edge to center glyph) + shift_y = unbroken_span_glyph_info->geometry.width * 0.5 * font_size_multiplier; + new_glyph.width = new_span.font_size * para.pango_items[unbroken_span.pango_item_index].font->Advance(unbroken_span_glyph_info->glyph, true); } - + new_glyph.y -= shift_y; } } else { // Horizontal text if( dominant_baseline == SP_CSS_BASELINE_AUTO ) dominant_baseline = SP_CSS_BASELINE_ALPHABETIC; + new_glyph.x += delta_x; new_glyph.y += delta_y; + new_glyph.y += new_span.font_size * para.pango_items[unbroken_span.pango_item_index].font->GetBaselines()[ dominant_baseline ]; new_glyph.width = unbroken_span_glyph_info->geometry.width * font_size_multiplier; @@ -810,7 +834,6 @@ void Layout::Calculator::_outputLine(ParagraphInfo const ¶, // for some reason pango returns zero width for invalid glyph characters (those empty boxes), so go to freetype for the info } - if (new_span.direction == RIGHT_TO_LEFT) { // pango wanted to give us glyphs in visual order but we refused, so we need to work // out where the cluster start is ourselves -- cgit v1.2.3 From 179538a2098fe6ae701bdb20e538b92ff7a4ffe7 Mon Sep 17 00:00:00 2001 From: Eduard Braun Date: Sat, 23 Sep 2017 20:01:24 +0200 Subject: Do not crash if no fonts are available Usually we fall back to "sans-serif" but if not a single fallback was available (this happens for example if the fontconfig configuration is invalid) Inkscape crashed. Fixed bug: - https://bugs.launchpad.net/inkscape/+bug/1716516 --- src/libnrtype/FontFactory.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/libnrtype') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index 5c6a96694..40e5d4ba1 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -689,9 +689,12 @@ font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail) pango_font_description_set_family(descr,"sans-serif"); res = Face(descr,false); pango_font_description_free(descr); + } else { + g_critical("Could not load any face for font '%s'.", pango_font_description_to_string(descr)); } } + if (res) { // Extract which OpenType tables are in the font. We'll make a list of all tables // regardless of which script and langauge they are in. This Harfbuzz code replaces // an earlier Pango version as the Pango functions are deprecated. @@ -836,6 +839,7 @@ font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail) hb_face_destroy (face); g_free(scripts_hb); + } } else { // already here res = loadedFaces[descr]; -- cgit v1.2.3 From 6b8c070aa2a30a15f3d3187fc35af0cfe662d354 Mon Sep 17 00:00:00 2001 From: Eduard Braun Date: Sat, 23 Sep 2017 20:02:45 +0200 Subject: cleanup: do not overwrite/free original font description (likely unproblematic but better be safe than sorry...) --- src/libnrtype/FontFactory.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index 40e5d4ba1..3b7b5b9b4 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -685,10 +685,10 @@ font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail) // no match if ( canFail ) { PANGO_DEBUG("falling back to 'sans-serif'\n"); - descr = pango_font_description_new(); - pango_font_description_set_family(descr,"sans-serif"); - res = Face(descr,false); - pango_font_description_free(descr); + PangoFontDescription *new_descr = pango_font_description_new(); + pango_font_description_set_family(new_descr, "sans-serif"); + res = Face(new_descr, false); + pango_font_description_free(new_descr); } else { g_critical("Could not load any face for font '%s'.", pango_font_description_to_string(descr)); } -- cgit v1.2.3 From 74d871992d7641101f8c26e934b96ae72d851c93 Mon Sep 17 00:00:00 2001 From: Eduard Braun Date: Sat, 23 Sep 2017 20:20:35 +0200 Subject: cleanup: put extraction of OpenType tables in separate function --- src/libnrtype/FontFactory.cpp | 291 +++++++++++++++++++++--------------------- 1 file changed, 147 insertions(+), 144 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index 3b7b5b9b4..e160fc277 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -627,6 +627,152 @@ Glib::ustring extract_tag( guint32 *tag ) { return tag_name; } +// Extract which OpenType tables are in the font. A list of all tables (regardless of which script and langauge +// they are in) will be stored as a std::map in the openTypeTables field of the font_instance +// This Harfbuzz code replaces an earlier Pango version as the Pango functions are deprecated. +void extract_openTypeTables(font_instance *res) { + // Empty map... bitmap fonts seem to be loaded multiple times. + res->openTypeTables.clear(); + + auto const face = hb_ft_face_create(res->theFace, NULL); + + // First time to get size of array + auto script_count = hb_ot_layout_table_get_script_tags(face, HB_OT_TAG_GSUB, 0, NULL, NULL); + auto const scripts_hb = g_new(hb_tag_t, script_count + 1); + + // Second time to fill array (this two step process was not necessary with Pango). + hb_ot_layout_table_get_script_tags(face, HB_OT_TAG_GSUB, 0, &script_count, scripts_hb); + + for(unsigned int i = 0; i < script_count; ++i) { + auto language_count = hb_ot_layout_script_get_language_tags(face, HB_OT_TAG_GSUB, i, 0, NULL, NULL); + + if(language_count > 0) { + auto const languages_hb = g_new(hb_tag_t, language_count + 1); + hb_ot_layout_script_get_language_tags(face, HB_OT_TAG_GSUB, i, 0, &language_count, languages_hb); + + for(unsigned int j = 0; j < language_count; ++j) { + auto feature_count = hb_ot_layout_language_get_feature_tags(face, HB_OT_TAG_GSUB, i, j, 0, NULL, NULL); + auto const features_hb = g_new(hb_tag_t, feature_count + 1); + hb_ot_layout_language_get_feature_tags(face, HB_OT_TAG_GSUB, i, j, 0, &feature_count, features_hb); + + for(unsigned int k = 0; k < feature_count; ++k) { + ++(res->openTypeTables[ extract_tag(&features_hb[k])]); + } + + g_free(features_hb); + } + + g_free(languages_hb); + } + else { + // Even if no languages are present there is still the default. + auto feature_count = hb_ot_layout_language_get_feature_tags(face, HB_OT_TAG_GSUB, i, + HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX, + 0, NULL, NULL); + auto const features_hb = g_new(hb_tag_t, feature_count + 1); + hb_ot_layout_language_get_feature_tags(face, HB_OT_TAG_GSUB, i, + HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX, + 0, &feature_count, features_hb); + + for(unsigned int k = 0; k < feature_count; ++k) { + ++(res->openTypeTables[ extract_tag(&features_hb[k])]); + } + + g_free(features_hb); + } + } + +// TODO: Ideally, we should use the HB_VERSION_ATLEAST macro here, +// but this was only released in harfbuzz >= 0.9.30 +// #if HB_VERSION_ATLEAST(1,2,3) +#if HB_VERSION_MAJOR*10000 + HB_VERSION_MINOR*100 + HB_VERSION_MICRO >= 10203 + // Find glyphs in OpenType substitution tables ('gsub'). + // Note that pango's functions are just dummies. Must use harfbuzz. + + // Loop over all tables + for (auto table: res->openTypeTables) { + + // Only look at style substitution tables ('salt', 'ss01', etc. but not 'ssty'). + if (table.first == "salt" || + (table.first[0] == 's' && table.first[1] == 's' && !(table.first[2] == 't') ) ) { + // std::cout << " Table: " << table.first << std::endl; + + Glib::ustring unicode_characters; + + unsigned int feature_index; + if ( hb_ot_layout_language_find_feature (face, HB_OT_TAG_GSUB, + 0, // Assume one script exists with index 0 + HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX, + HB_TAG(table.first[0], + table.first[1], + table.first[2], + table.first[3]), + &feature_index ) ) { + + // std::cout << " Found feature, number: " << feature_index << std::endl; + unsigned int lookup_indexes[32]; + unsigned int lookup_count = 32; + int count = hb_ot_layout_feature_get_lookups (face, HB_OT_TAG_GSUB, + feature_index, + 0, // Start + &lookup_count, + lookup_indexes ); + // std::cout << " Lookup count: " << count << " total: " << lookup_count << std::endl; + + if (count > 0) { + hb_set_t* glyphs_before = NULL; // hb_set_create(); + hb_set_t* glyphs_input = hb_set_create(); + hb_set_t* glyphs_after = NULL; // hb_set_create(); + hb_set_t* glyphs_output = NULL; // hb_set_create(); + + // For now, just look at first index + hb_ot_layout_lookup_collect_glyphs (face, HB_OT_TAG_GSUB, + lookup_indexes[0], + glyphs_before, + glyphs_input, + glyphs_after, + glyphs_output ); + + hb_font_t *font = hb_font_create (face); + + // Without this, all functions return 0, etc. + hb_ft_font_set_funcs (font); + + hb_codepoint_t codepoint = -1; + while (hb_set_next (glyphs_input, &codepoint)) { + + // There is a unicode to glyph mapping function but not the inverse! + for (hb_codepoint_t unicode_i = 0; unicode_i < 0xffff; ++unicode_i) { + hb_codepoint_t glyph = 0; + hb_font_get_nominal_glyph (font, unicode_i, &glyph); + if ( glyph == codepoint) { + unicode_characters += (gunichar)unicode_i; + continue; + } + } + } + res->openTypeSubstitutions[table.first] = unicode_characters; + + hb_set_destroy (glyphs_input); + hb_font_destroy (font); + } + } else { + // std::cout << " Did not find '" << table.first << "'!" << std::endl; + } + } + } + // for (auto table: res->openTypeSubstitutions) { + // std::cout << table.first << ": " << table.second << std::endl; + // } +#else + std::cerr << "Requires Harfbuzz 1.2.3 for visualizing alternative glyph OpenType tables. " + << "Compiled with: " << HB_VERSION_STRING << "." << std::endl; +#endif + + hb_face_destroy (face); + g_free(scripts_hb); +} + font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail) { #ifdef USE_PANGO_WIN32 @@ -695,150 +841,7 @@ font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail) } if (res) { - // Extract which OpenType tables are in the font. We'll make a list of all tables - // regardless of which script and langauge they are in. This Harfbuzz code replaces - // an earlier Pango version as the Pango functions are deprecated. - - // Empty map... bitmap fonts seem to be loaded multiple times. - res->openTypeTables.clear(); - - auto const face = hb_ft_face_create(res->theFace, NULL); - - // First time to get size of array - auto script_count = hb_ot_layout_table_get_script_tags(face, HB_OT_TAG_GSUB, 0, NULL, NULL); - auto const scripts_hb = g_new(hb_tag_t, script_count + 1); - - // Second time to fill array (this two step process was not necessary with Pango). - hb_ot_layout_table_get_script_tags(face, HB_OT_TAG_GSUB, 0, &script_count, scripts_hb); - - for(unsigned int i = 0; i < script_count; ++i) { - auto language_count = hb_ot_layout_script_get_language_tags(face, HB_OT_TAG_GSUB, i, 0, NULL, NULL); - - if(language_count > 0) { - auto const languages_hb = g_new(hb_tag_t, language_count + 1); - hb_ot_layout_script_get_language_tags(face, HB_OT_TAG_GSUB, i, 0, &language_count, languages_hb); - - for(unsigned int j = 0; j < language_count; ++j) { - auto feature_count = hb_ot_layout_language_get_feature_tags(face, HB_OT_TAG_GSUB, i, j, 0, NULL, NULL); - auto const features_hb = g_new(hb_tag_t, feature_count + 1); - hb_ot_layout_language_get_feature_tags(face, HB_OT_TAG_GSUB, i, j, 0, &feature_count, features_hb); - - for(unsigned int k = 0; k < feature_count; ++k) { - ++(res->openTypeTables[ extract_tag(&features_hb[k])]); - } - - g_free(features_hb); - } - - g_free(languages_hb); - } - else { - // Even if no languages are present there is still the default. - auto feature_count = hb_ot_layout_language_get_feature_tags(face, HB_OT_TAG_GSUB, i, - HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX, - 0, NULL, NULL); - auto const features_hb = g_new(hb_tag_t, feature_count + 1); - hb_ot_layout_language_get_feature_tags(face, HB_OT_TAG_GSUB, i, - HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX, - 0, &feature_count, features_hb); - - for(unsigned int k = 0; k < feature_count; ++k) { - ++(res->openTypeTables[ extract_tag(&features_hb[k])]); - } - - g_free(features_hb); - } - } - -// TODO: Ideally, we should use the HB_VERSION_ATLEAST macro here, -// but this was only released in harfbuzz >= 0.9.30 -// #if HB_VERSION_ATLEAST(1,2,3) -#if HB_VERSION_MAJOR*10000 + HB_VERSION_MINOR*100 + HB_VERSION_MICRO >= 10203 - // Find glyphs in OpenType substitution tables ('gsub'). - // Note that pango's functions are just dummies. Must use harfbuzz. - - // Loop over all tables - for (auto table: res->openTypeTables) { - - // Only look at style substitution tables ('salt', 'ss01', etc. but not 'ssty'). - if (table.first == "salt" || - (table.first[0] == 's' && table.first[1] == 's' && !(table.first[2] == 't') ) ) { - // std::cout << " Table: " << table.first << std::endl; - - Glib::ustring unicode_characters; - - unsigned int feature_index; - if ( hb_ot_layout_language_find_feature (face, HB_OT_TAG_GSUB, - 0, // Assume one script exists with index 0 - HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX, - HB_TAG(table.first[0], - table.first[1], - table.first[2], - table.first[3]), - &feature_index ) ) { - - // std::cout << " Found feature, number: " << feature_index << std::endl; - unsigned int lookup_indexes[32]; - unsigned int lookup_count = 32; - int count = hb_ot_layout_feature_get_lookups (face, HB_OT_TAG_GSUB, - feature_index, - 0, // Start - &lookup_count, - lookup_indexes ); - // std::cout << " Lookup count: " << count << " total: " << lookup_count << std::endl; - - if (count > 0) { - hb_set_t* glyphs_before = NULL; // hb_set_create(); - hb_set_t* glyphs_input = hb_set_create(); - hb_set_t* glyphs_after = NULL; // hb_set_create(); - hb_set_t* glyphs_output = NULL; // hb_set_create(); - - // For now, just look at first index - hb_ot_layout_lookup_collect_glyphs (face, HB_OT_TAG_GSUB, - lookup_indexes[0], - glyphs_before, - glyphs_input, - glyphs_after, - glyphs_output ); - - hb_font_t *font = hb_font_create (face); - - // Without this, all functions return 0, etc. - hb_ft_font_set_funcs (font); - - hb_codepoint_t codepoint = -1; - while (hb_set_next (glyphs_input, &codepoint)) { - - // There is a unicode to glyph mapping function but not the inverse! - for (hb_codepoint_t unicode_i = 0; unicode_i < 0xffff; ++unicode_i) { - hb_codepoint_t glyph = 0; - hb_font_get_nominal_glyph (font, unicode_i, &glyph); - if ( glyph == codepoint) { - unicode_characters += (gunichar)unicode_i; - continue; - } - } - } - res->openTypeSubstitutions[table.first] = unicode_characters; - - hb_set_destroy (glyphs_input); - hb_font_destroy (font); - } - } else { - // std::cout << " Did not find '" << table.first << "'!" << std::endl; - } - } - } - // for (auto table: res->openTypeSubstitutions) { - // std::cout << table.first << ": " << table.second << std::endl; - // } -#else - std::cerr << "Requires Harfbuzz 1.2.3 for visualizing alternative glyph OpenType tables. " - << "Compiled with: " << HB_VERSION_STRING << "." << std::endl; -#endif - - hb_face_destroy (face); - g_free(scripts_hb); + extract_openTypeTables(res); } } else { // already here -- cgit v1.2.3 From 66eb773e415c972774da3262d0cc00fae37a64db Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 25 Sep 2017 12:48:59 +0200 Subject: Minor code cleanup and better handling of non-spacing marks in upright vertical text. --- src/libnrtype/Layout-TNG-Compute.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG-Compute.cpp b/src/libnrtype/Layout-TNG-Compute.cpp index 38c3c48c4..7826faf0d 100644 --- a/src/libnrtype/Layout-TNG-Compute.cpp +++ b/src/libnrtype/Layout-TNG-Compute.cpp @@ -405,6 +405,16 @@ bool Layout::Calculator::_measureUnbrokenSpan(ParagraphInfo const ¶, // double glyph_y_offset = font_size_multiplier * info->geometry.y_offset; // std::cout << " glyph: " << info->glyph << " width: " << glyph_width << " x_offset: " << glyph_x_offset << " y_offset: " << glyph_y_offset << std::endl; + font_instance *font = para.pango_items[span->end.iter_span->pango_item_index].font; + double font_size = span->start.iter_span->font_size; + double glyph_h_advance = font_size * font->Advance(info->glyph, false); + double glyph_v_advance = font_size * font->Advance(info->glyph, true ); + // std::cout << " h_advance: " << glyph_h_advance << " v_advance: " << glyph_v_advance << std::endl; + // Geom::OptRect bbox = font->BBox(info->glyph); + // *bbox *= Geom::Scale(font_size); + // std::cout << " bbox: " << *bbox << std::endl; + // std::cout << " h_extent: " << bbox->width() << " v_extent: " << bbox->height() << std::endl; + if (_block_progression == LEFT_TO_RIGHT || _block_progression == RIGHT_TO_LEFT) { // Vertical text @@ -412,18 +422,18 @@ bool Layout::Calculator::_measureUnbrokenSpan(ParagraphInfo const ¶, (text_source->style->text_orientation.computed == SP_CSS_TEXT_ORIENTATION_MIXED && para.pango_items[span->end.iter_span->pango_item_index].item->analysis.gravity == PANGO_GRAVITY_SOUTH) ) { // Sideways orientation - char_width += span->start.iter_span->font_size * para.pango_items[span->end.iter_span->pango_item_index].font->Advance(info->glyph, false); + char_width += glyph_h_advance; } else { // Upright orientation guint32 c = *Glib::ustring::const_iterator(span->end.iter_span->input_stream_first_character.base() + span->end.char_byte); if (g_unichar_type (c) != G_UNICODE_NON_SPACING_MARK) { // Non-spacing marks should not contribute to width. Fonts may not report the correct advance, especially if the 'vmtx' table is missing. - char_width += span->start.iter_span->font_size * para.pango_items[span->end.iter_span->pango_item_index].font->Advance(info->glyph, true); + char_width += glyph_v_advance; } } } else { // Horizontal text - char_width += font_size_multiplier * span->end.iter_span->glyph_string->glyphs[span->end_glyph_index].geometry.width; + char_width += font_size_multiplier * info->geometry.width; } span->end_glyph_index++; } @@ -808,13 +818,16 @@ void Layout::Calculator::_outputLine(ParagraphInfo const ¶, para.pango_items[unbroken_span.pango_item_index].font->GetBaselines()[ SP_CSS_BASELINE_CENTRAL ] ); static double shift_y = 0; // Save to use with non_spacing marks (should be shifted the same amount as previous glyph). + static double shift_x = 0; // Subtract incorrect Pango inclusion of horizontal advance (https://bugzilla.gnome.org 787526) if (g_unichar_type (*iter_source_text) == G_UNICODE_NON_SPACING_MARK) { new_glyph.width = 0; - new_glyph.x += new_span.font_size; // Hack! + new_glyph.x += shift_x; // Hack + shift_x = 0; } else { // Glyph reference point is center (shift: left edge to center glyph) shift_y = unbroken_span_glyph_info->geometry.width * 0.5 * font_size_multiplier; new_glyph.width = new_span.font_size * para.pango_items[unbroken_span.pango_item_index].font->Advance(unbroken_span_glyph_info->glyph, true); + shift_x = new_span.font_size * para.pango_items[unbroken_span.pango_item_index].font->Advance(unbroken_span_glyph_info->glyph, false); } new_glyph.y -= shift_y; } -- cgit v1.2.3 From 342812bdbc6b67ab096c6e9c55bf5370163a2863 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 26 Sep 2017 13:22:42 +0200 Subject: Fix error when vertical text has 'text-orientation' value 'sideways'. --- src/libnrtype/Layout-TNG-Compute.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG-Compute.cpp b/src/libnrtype/Layout-TNG-Compute.cpp index 7826faf0d..eca795994 100644 --- a/src/libnrtype/Layout-TNG-Compute.cpp +++ b/src/libnrtype/Layout-TNG-Compute.cpp @@ -1787,7 +1787,7 @@ bool Layout::Calculator::calculate() // Vertical text, CJK pango_context_set_base_gravity(_pango_context, PANGO_GRAVITY_EAST); - if( _flow._blockTextOrientation() != SP_CSS_TEXT_ORIENTATION_MIXED ) { + if( _flow._blockTextOrientation() == SP_CSS_TEXT_ORIENTATION_UPRIGHT ) { pango_context_set_gravity_hint(_pango_context, PANGO_GRAVITY_HINT_STRONG); } } else { -- cgit v1.2.3 From e0957537cd0938313803c290a2f3922a3889e6f1 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Sun, 1 Oct 2017 17:49:26 +0200 Subject: Removed all GSList occurences in .h files --- src/libnrtype/Layout-TNG-Output.cpp | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index 7f20dee95..9a73b9eca 100644 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -800,7 +800,7 @@ void Layout::fitToPathAlign(SVGLength const &startOffset, Path const &path) SPCurve *Layout::convertToCurves(iterator const &from_glyph, iterator const &to_glyph) const { - GSList *cc = NULL; + std::list cc; for (int glyph_index = from_glyph._glyph_index ; glyph_index < to_glyph._glyph_index ; glyph_index++) { Geom::Affine glyph_matrix; @@ -811,22 +811,14 @@ SPCurve *Layout::convertToCurves(iterator const &from_glyph, iterator const &to_ if (pathv) { Geom::PathVector pathv_trans = (*pathv) * glyph_matrix; SPCurve *c = new SPCurve(pathv_trans); - if (c) cc = g_slist_prepend(cc, c); + if (c) cc.push_back(c); } } - cc = g_slist_reverse(cc); + SPCurve *curve = new SPCurve(cc); - SPCurve *curve; - if ( cc ) { - curve = SPCurve::concat(cc); - } else { - curve = new SPCurve(); - } - - while (cc) { + for (auto i:cc) { /* fixme: This is dangerous, as we are mixing art_alloc and g_new */ - reinterpret_cast(cc->data)->unref(); - cc = g_slist_remove(cc, cc->data); + i->unref(); } return curve; -- cgit v1.2.3 From 398d69e9d27bd5e0a8db85cc799478534b9db52f Mon Sep 17 00:00:00 2001 From: Eduard Braun Date: Mon, 16 Oct 2017 22:27:05 +0200 Subject: Revive pango_win32 backend With these changes it's compiling and rendering text, however there seems to be an issue with setting font styles (e.g. font size is not set properly initially). OpenType font features are not supported. See https://bugs.launchpad.net/inkscape/+bug/1416674 for some history --- src/libnrtype/FontFactory.cpp | 2 ++ src/libnrtype/FontInstance.cpp | 12 ++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index e160fc277..b2baeb2f0 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -634,6 +634,7 @@ void extract_openTypeTables(font_instance *res) { // Empty map... bitmap fonts seem to be loaded multiple times. res->openTypeTables.clear(); +#ifndef USE_PANGO_WIN32 auto const face = hb_ft_face_create(res->theFace, NULL); // First time to get size of array @@ -771,6 +772,7 @@ void extract_openTypeTables(font_instance *res) { hb_face_destroy (face); g_free(scripts_hb); +#endif // USE_PANGO_WIN32 } font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail) diff --git a/src/libnrtype/FontInstance.cpp b/src/libnrtype/FontInstance.cpp index 7a16fc0c3..57aa22d48 100644 --- a/src/libnrtype/FontInstance.cpp +++ b/src/libnrtype/FontInstance.cpp @@ -556,10 +556,10 @@ bool font_instance::FontDecoration( double &underline_position, double &underl return false; } double scale=1.0/parent->fontSize; - underline_position = fabs(otm.otmUnderscorePosition *scale); - underline_thickness = fabs(otm.otmUnderscoreSize *scale); - linethrough_position = fabs(otm.otmStrikeoutPosition *scale); - linethrough_thickness = fabs(otm.otmStrikeoutSize *scale); + underline_position = fabs(otm.otmsUnderscorePosition *scale); + underline_thickness = fabs(otm.otmsUnderscoreSize *scale); + linethrough_position = fabs(otm.otmsStrikeoutPosition *scale); + linethrough_thickness = fabs(otm.otmsStrikeoutSize *scale); #else if ( theFace->units_per_EM == 0 ) { return false; // bitmap font @@ -683,12 +683,12 @@ void font_instance::FindFontMetrics() { if ( theFace ) { #ifdef USE_PANGO_WIN32 - + OUTLINETEXTMETRIC otm; if ( GetOutlineTextMetrics(parent->hScreenDC,sizeof(otm),&otm) ) { double scale=1.0/parent->fontSize; _ascent = fabs(otm.otmMacAscent * scale); _descent = fabs(otm.otmMacDescent * scale); - _xheight = fabs(otm.otmXHeight * scale); + _xheight = fabs(otm.otmsXHeight * scale); _ascent_max = fabs(otm.otmAscent * scale); _descent_max = fabs(otm.otmDescent * scale); -- cgit v1.2.3 From f113fba09e2df478335e983f04ad09798c774fe7 Mon Sep 17 00:00:00 2001 From: Eduard Braun Date: Tue, 17 Oct 2017 19:47:08 +0200 Subject: Replace deprecated call to pango_win32_get_context --- src/libnrtype/FontFactory.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index b2baeb2f0..bf4cbc56f 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -89,26 +89,20 @@ font_factory::font_factory(void) : nbEnt(0), // Note: this "ents" cache only keeps fonts from being unreffed, does not speed up access maxEnt(32), ents(static_cast(g_malloc(maxEnt*sizeof(font_entry)))), - #ifdef USE_PANGO_WIN32 fontServer(pango_win32_font_map_for_display()), - fontContext(pango_win32_get_context()), pangoFontCache(pango_win32_font_map_get_font_cache(fontServer)), hScreenDC(pango_win32_get_dc()), #else fontServer(pango_ft2_font_map_new()), - fontContext(0), #endif + fontContext(pango_font_map_create_context(fontServer)), fontSize(512), loadedPtr(new FaceMapType()) { -#ifdef USE_PANGO_WIN32 -#else +#ifndef USE_PANGO_WIN32 pango_ft2_font_map_set_resolution(PANGO_FT2_FONT_MAP(fontServer), 72, 72); - - fontContext = pango_font_map_create_context(fontServer); - pango_ft2_font_map_set_default_substitute(PANGO_FT2_FONT_MAP(fontServer), FactorySubstituteFunc, this, -- cgit v1.2.3 From d6c5424f69aeb91cf1cfeba262b5466a42dd95a5 Mon Sep 17 00:00:00 2001 From: Eduard Braun Date: Thu, 19 Oct 2017 23:41:25 +0200 Subject: FontFactory: Add function to add additional font directories --- src/libnrtype/FontFactory.cpp | 32 ++++++++++++++++++++++++++++++++ src/libnrtype/FontFactory.h | 3 +++ 2 files changed, 35 insertions(+) (limited to 'src/libnrtype') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index bf4cbc56f..677b8abe7 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -17,8 +17,11 @@ #endif #include +#include +#include #include #include +#include "io/sys.h" #include "libnrtype/FontFactory.h" #include "libnrtype/font-instance.h" #include "util/unordered-containers.h" @@ -914,6 +917,35 @@ void font_factory::AddInCache(font_instance *who) nbEnt++; } +void font_factory::AddFontsDir(char const *utf8dir) +{ +#ifdef USE_PANGO_WIN32 + g_info("Adding additional font directories only supported for fontconfig backend."); +#else + if (!Inkscape::IO::file_test(utf8dir, G_FILE_TEST_IS_DIR)) { + g_warning("Fonts dir '%s' does not exist and will be ignored.", utf8dir); + return; + } + + gchar *dir; +# ifdef WIN32 + dir = g_win32_locale_filename_from_utf8(utf8dir); +# else + dir = g_filename_from_utf8(utf8dir, -1, NULL, NULL, NULL); +# endif + + FcConfig *conf = pango_fc_font_map_get_config(PANGO_FC_FONT_MAP(fontServer)); + FcBool res = FcConfigAppFontAddDir(conf, (FcChar8 const *)dir); + if (res = FcTrue) { + g_info("Fonts dir '%s' added successfully.", utf8dir); + } else { + g_warning("Could not add fonts dir '%s'.", utf8dir); + } + + g_free(dir); +#endif +} + /* Local Variables: mode:c++ diff --git a/src/libnrtype/FontFactory.h b/src/libnrtype/FontFactory.h index 41c4cb6eb..c273be2f4 100644 --- a/src/libnrtype/FontFactory.h +++ b/src/libnrtype/FontFactory.h @@ -136,6 +136,9 @@ public: // internal void AddInCache(font_instance *who); + /// Add a directory from which to include additional fonts + void AddFontsDir(char const *utf8dir); + private: void* loadedPtr; -- cgit v1.2.3 From de6d47ed290e02aa4bdc64d6cea5a6c8c20e61c7 Mon Sep 17 00:00:00 2001 From: Eduard Braun Date: Mon, 23 Oct 2017 00:10:41 +0200 Subject: Fix compilation on Ubuntu Trusty pango_fc_font_map_get_config() is available since pango 1.38 but trusty only has pango 1.36. While calling this function is the "proper" way to get the FcConfig attached to the FontFactory's font map, FcConfigAppFontAddDir() reference says "If config is NULL, the current configuration is used." and it seems to the current configuration is suitable to use in this case (which might change if we ever start to use multiple font maps with different FcConfig's attached but should be fine for now...) --- src/libnrtype/FontFactory.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index 677b8abe7..95537734d 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -934,7 +934,10 @@ void font_factory::AddFontsDir(char const *utf8dir) dir = g_filename_from_utf8(utf8dir, -1, NULL, NULL, NULL); # endif - FcConfig *conf = pango_fc_font_map_get_config(PANGO_FC_FONT_MAP(fontServer)); + FcConfig *conf = NULL; +# if PANGO_VERSION_CHECK(1,38,0) + pango_fc_font_map_get_config(PANGO_FC_FONT_MAP(fontServer)); +# endif FcBool res = FcConfigAppFontAddDir(conf, (FcChar8 const *)dir); if (res = FcTrue) { g_info("Fonts dir '%s' added successfully.", utf8dir); -- cgit v1.2.3 From fd52c97cdbf621ea9e869611be4d5fb9bec90ff7 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Wed, 25 Oct 2017 13:53:33 +0200 Subject: Add limited support for CSS 'font-face' rule. Basically, any ttf or otf file found will be loaded but no custom matching is done nor is the 'font-family' menu updated. --- src/libnrtype/FontFactory.cpp | 32 ++++++++++++++++++++++++++++++++ src/libnrtype/FontFactory.h | 3 +++ 2 files changed, 35 insertions(+) (limited to 'src/libnrtype') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index 95537734d..2b1087eec 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -949,6 +949,38 @@ void font_factory::AddFontsDir(char const *utf8dir) #endif } +void font_factory::AddFontFile(char const *utf8file) +{ +#ifdef USE_PANGO_WIN32 + g_info("Adding additional font only supported for fontconfig backend."); +#else + if (!Inkscape::IO::file_test(utf8file, G_FILE_TEST_IS_REGULAR)) { + g_warning("Font file '%s' does not exist and will be ignored.", utf8file); + return; + } + + gchar *file; +# ifdef WIN32 + file = g_win32_locale_filename_from_utf8(utf8file); +# else + file = g_filename_from_utf8(utf8file, -1, NULL, NULL, NULL); +# endif + + FcConfig *conf = NULL; +# if PANGO_VERSION_CHECK(1,38,0) + pango_fc_font_map_get_config(PANGO_FC_FONT_MAP(fontServer)); +# endif + FcBool res = FcConfigAppFontAddFile(conf, (FcChar8 const *)file); + if (res = FcTrue) { + g_info("Font file '%s' added successfully.", utf8file); + } else { + g_warning("Could not add font file '%s'.", utf8file); + } + + g_free(file); +#endif +} + /* Local Variables: mode:c++ diff --git a/src/libnrtype/FontFactory.h b/src/libnrtype/FontFactory.h index c273be2f4..12260f99a 100644 --- a/src/libnrtype/FontFactory.h +++ b/src/libnrtype/FontFactory.h @@ -139,6 +139,9 @@ public: /// Add a directory from which to include additional fonts void AddFontsDir(char const *utf8dir); + /// Add a an additional font. + void AddFontFile(char const *utf8file); + private: void* loadedPtr; -- cgit v1.2.3 From f346413e6258381d8e30825f22d8cd40fdf806bc Mon Sep 17 00:00:00 2001 From: Eduard Braun Date: Wed, 25 Oct 2017 23:05:44 +0200 Subject: Fix code accidentally made useless in de6d47ed290e02aa4bdc64d6cea5a6c8c20e61c7 --- src/libnrtype/FontFactory.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index 2b1087eec..9c62e5483 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -936,7 +936,7 @@ void font_factory::AddFontsDir(char const *utf8dir) FcConfig *conf = NULL; # if PANGO_VERSION_CHECK(1,38,0) - pango_fc_font_map_get_config(PANGO_FC_FONT_MAP(fontServer)); + conf = pango_fc_font_map_get_config(PANGO_FC_FONT_MAP(fontServer)); # endif FcBool res = FcConfigAppFontAddDir(conf, (FcChar8 const *)dir); if (res = FcTrue) { @@ -968,7 +968,7 @@ void font_factory::AddFontFile(char const *utf8file) FcConfig *conf = NULL; # if PANGO_VERSION_CHECK(1,38,0) - pango_fc_font_map_get_config(PANGO_FC_FONT_MAP(fontServer)); + conf = pango_fc_font_map_get_config(PANGO_FC_FONT_MAP(fontServer)); # endif FcBool res = FcConfigAppFontAddFile(conf, (FcChar8 const *)file); if (res = FcTrue) { -- cgit v1.2.3 From 073da60232635543fe12186d4fcb81a3da15f0f2 Mon Sep 17 00:00:00 2001 From: Simon Wells Date: Fri, 3 Nov 2017 12:25:58 +1300 Subject: change assignment to equality --- src/libnrtype/FontFactory.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/libnrtype') diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index 9c62e5483..90df81261 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -939,7 +939,7 @@ void font_factory::AddFontsDir(char const *utf8dir) conf = pango_fc_font_map_get_config(PANGO_FC_FONT_MAP(fontServer)); # endif FcBool res = FcConfigAppFontAddDir(conf, (FcChar8 const *)dir); - if (res = FcTrue) { + if (res == FcTrue) { g_info("Fonts dir '%s' added successfully.", utf8dir); } else { g_warning("Could not add fonts dir '%s'.", utf8dir); @@ -971,7 +971,7 @@ void font_factory::AddFontFile(char const *utf8file) conf = pango_fc_font_map_get_config(PANGO_FC_FONT_MAP(fontServer)); # endif FcBool res = FcConfigAppFontAddFile(conf, (FcChar8 const *)file); - if (res = FcTrue) { + if (res == FcTrue) { g_info("Font file '%s' added successfully.", utf8file); } else { g_warning("Could not add font file '%s'.", utf8file); -- cgit v1.2.3