X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Flibnrtype%2FLayout-TNG-Output.cpp;h=68d7752c30af2c516fb178d5f342761ce5e92d96;hb=ac63672b8bd0ad9539384d4eac6e27875d4d2693;hp=b6249248bc90775c4ec7ce154870a77f15f94e77;hpb=3f77925d9430368418b9af29fbb5b0969b95bc47;p=inkscape.git diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp index b6249248b..68d7752c3 100755 --- a/src/libnrtype/Layout-TNG-Output.cpp +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -8,6 +8,8 @@ * * Released under GNU GPL, read the file 'COPYING' for more information */ +#include +#include #include "Layout-TNG.h" #include "display/nr-arena-glyphs.h" #include "style.h" @@ -17,6 +19,19 @@ #include "libnr/nr-scale-matrix-ops.h" #include "font-instance.h" #include "svg/svg-length.h" +#include "extension/internal/cairo-render-context.h" + +namespace Inkscape { + namespace Extension { + namespace Internal { + class CairoRenderContext; + class CairoGlyphInfo; + } + } +} + +using Inkscape::Extension::Internal::CairoRenderContext; +using Inkscape::Extension::Internal::CairoGlyphInfo; namespace Inkscape { namespace Text { @@ -87,31 +102,33 @@ void Layout::getBoundingBox(NRRect *bounding_box, NR::Matrix const &transform, i { for (unsigned glyph_index = 0 ; glyph_index < _glyphs.size() ; glyph_index++) { if (_characters[_glyphs[glyph_index].in_character].in_glyph == -1) continue; - if (start != -1 && _glyphs[glyph_index].in_character < start) continue; + if (start != -1 && (int) _glyphs[glyph_index].in_character < start) continue; if (length != -1) { if (start == -1) start = 0; - if (_glyphs[glyph_index].in_character > start + length) continue; + if ((int) _glyphs[glyph_index].in_character > start + length) continue; } // this could be faster NRMatrix glyph_matrix; _getGlyphTransformMatrix(glyph_index, &glyph_matrix); NR::Matrix total_transform = glyph_matrix; total_transform *= transform; - NR::Rect glyph_rect = _glyphs[glyph_index].span(this).font->BBox(_glyphs[glyph_index].glyph); - NR::Point bmi = glyph_rect.min(), bma = glyph_rect.max(); - NR::Point tlp(bmi[0],bmi[1]), trp(bma[0],bmi[1]), blp(bmi[0],bma[1]), brp(bma[0],bma[1]); - tlp *= total_transform; - trp *= total_transform; - blp *= total_transform; - brp *= total_transform; - glyph_rect = NR::Rect(tlp,trp); - glyph_rect.expandTo(blp); - glyph_rect.expandTo(brp); - if ( (glyph_rect.min())[0] < bounding_box->x0 ) bounding_box->x0=(glyph_rect.min())[0]; - if ( (glyph_rect.max())[0] > bounding_box->x1 ) bounding_box->x1=(glyph_rect.max())[0]; - if ( (glyph_rect.min())[1] < bounding_box->y0 ) bounding_box->y0=(glyph_rect.min())[1]; - if ( (glyph_rect.max())[1] > bounding_box->y1 ) bounding_box->y1=(glyph_rect.max())[1]; + NR::Maybe glyph_rect = _glyphs[glyph_index].span(this).font->BBox(_glyphs[glyph_index].glyph); + if (glyph_rect) { + NR::Point bmi = glyph_rect->min(), bma = glyph_rect->max(); + NR::Point tlp(bmi[0],bmi[1]), trp(bma[0],bmi[1]), blp(bmi[0],bma[1]), brp(bma[0],bma[1]); + tlp *= total_transform; + trp *= total_transform; + blp *= total_transform; + brp *= total_transform; + *glyph_rect = NR::Rect(tlp,trp); + glyph_rect->expandTo(blp); + glyph_rect->expandTo(brp); + if ( (glyph_rect->min())[0] < bounding_box->x0 ) bounding_box->x0=(glyph_rect->min())[0]; + if ( (glyph_rect->max())[0] > bounding_box->x1 ) bounding_box->x1=(glyph_rect->max())[0]; + if ( (glyph_rect->min())[1] < bounding_box->y0 ) bounding_box->y0=(glyph_rect->min())[1]; + if ( (glyph_rect->max())[1] > bounding_box->y1 ) bounding_box->y1=(glyph_rect->max())[1]; + } } } @@ -145,7 +162,7 @@ void Layout::print(SPPrintContext *ctx, sp_print_fill(ctx, &abp, &ctm, text_source->style, pbox, dbox, bbox); if (text_source->style->stroke.type != SP_PAINT_TYPE_NONE) sp_print_stroke(ctx, &abp, &ctm, text_source->style, pbox, dbox, bbox); - nr_free(abp.path); + g_free(abp.path); } glyph_index++; } else { @@ -191,6 +208,116 @@ void Layout::print(SPPrintContext *ctx, } } +#ifdef HAVE_CAIRO_PDF +void Layout::showGlyphs(CairoRenderContext *ctx) const +{ + if (_input_stream.empty()) return; + + bool clip_mode = false;//(ctx->getRenderMode() == CairoRenderContext::RENDER_MODE_CLIP); + std::vector glyphtext; + + for (unsigned glyph_index = 0 ; glyph_index < _glyphs.size() ; ) { + if (_characters[_glyphs[glyph_index].in_character].in_glyph == -1) { + // invisible glyphs + unsigned same_character = _glyphs[glyph_index].in_character; + while (_glyphs[glyph_index].in_character == same_character) + glyph_index++; + continue; + } + Span const &span = _spans[_characters[_glyphs[glyph_index].in_character].in_span]; + InputStreamTextSource const *text_source = static_cast(_input_stream[span.in_input_stream_item]); + + NRMatrix glyph_matrix; + _getGlyphTransformMatrix(glyph_index, &glyph_matrix); + if (clip_mode) { + NArtBpath *bpath = (NArtBpath*)span.font->ArtBPath(_glyphs[glyph_index].glyph); + if (bpath) { + NArtBpath *abp = nr_artpath_affine(bpath, glyph_matrix); + NRBPath bpath; + bpath.path = abp; + SPStyle const *style = text_source->style; + ctx->renderPath(&bpath, style, NULL); + g_free(abp); + } + glyph_index++; + continue; + } + + NRMatrix font_matrix; + if (_path_fitted == NULL) { + font_matrix = glyph_matrix; + font_matrix[4] = 0; + font_matrix[5] = 0; + } else { + nr_matrix_set_identity(&font_matrix); + } + + Glib::ustring::const_iterator span_iter = span.input_stream_first_character; + unsigned char_index = _glyphs[glyph_index].in_character; + unsigned original_span = _characters[char_index].in_span; + while (char_index && _characters[char_index - 1].in_span == original_span) { + char_index--; + span_iter++; + } + + // try to output as many characters as possible in one go + Glib::ustring span_string; + unsigned this_span_index = _characters[_glyphs[glyph_index].in_character].in_span; + unsigned int first_index = glyph_index; + glyphtext.clear(); + do { + span_string += *span_iter; + span_iter++; + + unsigned same_character = _glyphs[glyph_index].in_character; + while (glyph_index < _glyphs.size() && _glyphs[glyph_index].in_character == same_character) { + if (glyph_index != first_index) + _getGlyphTransformMatrix(glyph_index, &glyph_matrix); + + CairoGlyphInfo info; + info.index = _glyphs[glyph_index].glyph; + if (_path_fitted == NULL) { + info.x = glyph_matrix.c[4]; + info.y = glyph_matrix.c[5]; + } else { + info.x = 0; + info.y = 0; + } + glyphtext.push_back(info); + + glyph_index++; + } + } while (glyph_index < _glyphs.size() + && _path_fitted == NULL + && nr_matrix_test_transform_equal(&font_matrix, &glyph_matrix, NR_EPSILON) + && _characters[_glyphs[glyph_index].in_character].in_span == this_span_index); + + // remove vertical flip + font_matrix[3] *= -1.0; + + SPStyle const *style = text_source->style; + float opacity = SP_SCALE24_TO_FLOAT(style->opacity.value); + + if (_path_fitted) { + ctx->pushState(); + ctx->transform(&glyph_matrix); + } else if (opacity != 1.0) { + ctx->pushState(); + ctx->setStateForStyle(style); + ctx->pushLayer(); + } + if (glyph_index - first_index > 0) + ctx->renderGlyphtext(span.font->pFont, &font_matrix, glyphtext, style); + if (_path_fitted) + ctx->popState(); + else if (opacity != 1.0) { + ctx->popLayer(); + ctx->popState(); + } + } +} +#endif + // these functions are for dumpAsText() only. No need to translate static char const *direction_to_text(Layout::Direction d) { @@ -218,7 +345,9 @@ static char const *weight_to_text(PangoWeight w) switch (w) { case PANGO_WEIGHT_ULTRALIGHT: return "ultralight"; case PANGO_WEIGHT_LIGHT : return "light"; +#if GTK_CHECK_VERSION(2,6,0) case PANGO_WEIGHT_SEMIBOLD : return "semibold"; +#endif case PANGO_WEIGHT_NORMAL : return "normalweight"; case PANGO_WEIGHT_BOLD : return "bold"; case PANGO_WEIGHT_ULTRABOLD : return "ultrabold";