diff --git a/src/extension/internal/cairo-render-context.cpp b/src/extension/internal/cairo-render-context.cpp
index 61d40ea4eca2bea2d18e5210ca065e6a88866535..a040d5c099c387a9f0bce9ccc2d59abc1f52675c 100644 (file)
# include "config.h"
#endif
-#ifdef HAVE_CAIRO_PDF
-
#ifndef PANGO_ENABLE_BACKEND
#define PANGO_ENABLE_BACKEND
#endif
#include <libnr/n-art-bpath.h>
#include <libnr/nr-matrix-ops.h>
#include <libnr/nr-matrix-fns.h>
+#include <libnr/nr-matrix-scale-ops.h>
#include <libnr/nr-matrix-translate-ops.h>
#include <libnr/nr-scale-matrix-ops.h>
#endif
-#ifndef PANGO_ENABLE_BACKEND
+#ifdef CAIRO_HAS_FT_FONT
#include <cairo-ft.h>
#endif
@@ -106,6 +105,11 @@ static cairo_status_t _write_callback(void *closure, const unsigned char *data,
CairoRenderContext::CairoRenderContext(CairoRenderer *parent) :
_dpi(72),
+ _pdf_level(0),
+ _ps_level(1),
+ _is_texttopath(FALSE),
+ _is_filtertobitmap(FALSE),
+ _bitmapresolution(72),
_stream(NULL),
_is_valid(FALSE),
_vector_based_target(FALSE),
// only opacity & overflow is stored for now
_state->opacity = SP_SCALE24_TO_FLOAT(style->opacity.value);
_state->has_overflow = (style->overflow.set && style->overflow.value != SP_CSS_OVERFLOW_VISIBLE);
+ _state->has_filtereffect = (style->filter.set != 0) ? TRUE : FALSE;
if (style->fill.isPaintserver() || style->stroke.isPaintserver())
_state->merge_opacity = FALSE;
return true;
}
+void CairoRenderContext::setPSLevel(unsigned int level)
+{
+ _ps_level = level;
+}
+
+unsigned int CairoRenderContext::getPSLevel(void)
+{
+ return _ps_level;
+}
+
+void CairoRenderContext::setPDFLevel(unsigned int level)
+{
+ _pdf_level = level;
+}
+
+void CairoRenderContext::setTextToPath(bool texttopath)
+{
+ _is_texttopath = texttopath;
+}
+
+void CairoRenderContext::setFilterToBitmap(bool filtertobitmap)
+{
+ _is_filtertobitmap = filtertobitmap;
+}
+
+bool CairoRenderContext::getFilterToBitmap(void)
+{
+ return _is_filtertobitmap;
+}
+
+void CairoRenderContext::setBitmapResolution(int resolution)
+{
+ _bitmapresolution = resolution;
+}
+
+int CairoRenderContext::getBitmapResolution(void)
+{
+ return _bitmapresolution;
+}
+
cairo_surface_t*
CairoRenderContext::getSurface(void)
{
CairoRenderState *state = (CairoRenderState*)g_malloc(sizeof(CairoRenderState));
g_assert( state != NULL );
+ state->has_filtereffect = FALSE;
state->merge_opacity = TRUE;
state->opacity = 1.0;
state->need_layer = FALSE;
@@ -649,6 +695,10 @@ CairoRenderContext::addClippingRect(double x, double y, double width, double hei
bool
CairoRenderContext::setupSurface(double width, double height)
{
+ // Is the surface already set up?
+ if (_is_valid)
+ return true;
+
if (_vector_based_target && _stream == NULL)
return false;
#ifdef CAIRO_HAS_PS_SURFACE
case CAIRO_SURFACE_TYPE_PS:
surface = cairo_ps_surface_create_for_stream(Inkscape::Extension::Internal::_write_callback, _stream, width, height);
+#if (CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 5, 2))
+ if(CAIRO_STATUS_SUCCESS != cairo_surface_status(surface)) {
+ return FALSE;
+ }
+ cairo_ps_surface_restrict_to_level (surface, (cairo_ps_level_t)_ps_level);
+#endif
break;
#endif
default:
break;
}
+ return _finishSurfaceSetup (surface);
+}
+
+bool
+CairoRenderContext::setSurfaceTarget(cairo_surface_t *surface, bool is_vector)
+{
+ if (_is_valid || !surface)
+ return false;
+
+ _vector_based_target = is_vector;
+ bool ret = _finishSurfaceSetup (surface);
+ if (ret)
+ cairo_surface_reference (surface);
+ return ret;
+}
+
+bool
+CairoRenderContext::_finishSurfaceSetup(cairo_surface_t *surface)
+{
+ if(surface == NULL) {
+ return FALSE;
+ }
+ if(CAIRO_STATUS_SUCCESS != cairo_surface_status(surface)) {
+ return FALSE;
+ }
+
_cr = cairo_create(surface);
_surface = surface;
_is_valid = FALSE;
- if (_vector_based_target) {
+ if (_vector_based_target && _stream) {
/* Flush stream to be sure. */
(void) fflush(_stream);
}
void
-CairoRenderContext::transform(NRMatrix const *transform)
+CairoRenderContext::transform(NR::Matrix const *transform)
{
g_assert( _is_valid );
}
void
-CairoRenderContext::setTransform(NRMatrix const *transform)
+CairoRenderContext::setTransform(NR::Matrix const *transform)
{
g_assert( _is_valid );
}
void
-CairoRenderContext::getTransform(NRMatrix *copy) const
+CairoRenderContext::getTransform(NR::Matrix *copy) const
{
g_assert( _is_valid );
}
void
-CairoRenderContext::getParentTransform(NRMatrix *copy) const
+CairoRenderContext::getParentTransform(NR::Matrix *copy) const
{
g_assert( _is_valid );
CairoRenderState *parent_state = getParentState();
- memcpy(copy, &parent_state->transform, sizeof(NRMatrix));
+ memcpy(copy, &parent_state->transform, sizeof(NR::Matrix));
}
void
@@ -812,9 +894,9 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver
SPPattern *pat = SP_PATTERN (paintserver);
- NRMatrix ps2user, pcs2dev;
- nr_matrix_set_identity(&ps2user);
- nr_matrix_set_identity(&pcs2dev);
+ NR::Matrix ps2user, pcs2dev;
+ ps2user.set_identity();
+ pcs2dev.set_identity();
double x = pattern_x(pat);
double y = pattern_y(pat);
@@ -839,8 +921,8 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver
}
// apply pattern transformation
- NRMatrix pattern_transform(pattern_patternTransform(pat));
- nr_matrix_multiply(&ps2user, &ps2user, &pattern_transform);
+ NR::Matrix pattern_transform(pattern_patternTransform(pat));
+ ps2user *= pattern_transform;
// create pattern contents coordinate system
if (pat->viewBox_set) {
@@ -868,8 +950,8 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver
// calculate the size of the surface which has to be created
// the scaling needs to be taken into account in the ctm after the pattern transformation
- NRMatrix temp;
- nr_matrix_multiply(&temp, &pattern_transform, &_state->transform);
+ NR::Matrix temp;
+ temp = pattern_transform * _state->transform;
double width_scaler = sqrt(temp[0] * temp[0] + temp[2] * temp[2]);
double height_scaler = sqrt(temp[1] * temp[1] + temp[3] * temp[3]);
@@ -890,12 +972,8 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver
double scale_height = surface_height / (bbox_height_scaler * height);
if (scale_width != 1.0 || scale_height != 1.0 || _vector_based_target) {
TRACE(("needed to scale with %f %f\n", scale_width, scale_height));
- NRMatrix scale;
- nr_matrix_set_scale(&scale, 1.0 / scale_width, 1.0 / scale_height);
- nr_matrix_multiply(&pcs2dev, &pcs2dev, &scale);
-
- nr_matrix_set_scale(&scale, scale_width, scale_height);
- nr_matrix_multiply(&ps2user, &ps2user, &scale);
+ pcs2dev *= NR::scale(1.0 / scale_width, 1.0 / scale_height);
+ ps2user *= NR::scale(scale_width, scale_height);
}
pattern_ctx->setTransform(&pcs2dev);
@@ -1170,7 +1248,7 @@ CairoRenderContext::renderPath(NRBPath const *bpath, SPStyle const *style, NRRec
cairo_set_fill_rule(_cr, CAIRO_FILL_RULE_WINDING);
}
cairo_fill(_cr);
- cairo_surface_write_to_png (_surface, "gtar2.png");
+ TEST(cairo_surface_write_to_png (_surface, "pathmask.png"));
}
return true;
}
@@ -1220,7 +1298,7 @@ CairoRenderContext::renderPath(NRBPath const *bpath, SPStyle const *style, NRRec
bool
CairoRenderContext::renderImage(guchar *px, unsigned int w, unsigned int h, unsigned int rs,
- NRMatrix const *image_transform, SPStyle const *style)
+ NR::Matrix const *image_transform, SPStyle const *style)
{
g_assert( _is_valid );
@@ -1323,7 +1401,7 @@ CairoRenderContext::_showGlyphs(cairo_t *cr, PangoFont *font, std::vector<CairoG
i++;
}
- if (is_stroke)
+ if (is_stroke || _is_texttopath)
cairo_glyph_path(cr, glyphs, num_glyphs - num_invalid_glyphs);
else
cairo_show_glyphs(cr, glyphs, num_glyphs - num_invalid_glyphs);
@@ -1335,7 +1413,7 @@ CairoRenderContext::_showGlyphs(cairo_t *cr, PangoFont *font, std::vector<CairoG
}
bool
-CairoRenderContext::renderGlyphtext(PangoFont *font, NRMatrix const *font_matrix,
+CairoRenderContext::renderGlyphtext(PangoFont *font, NR::Matrix const *font_matrix,
std::vector<CairoGlyphInfo> const &glyphtext, SPStyle const *style)
{
// create a cairo_font_face from PangoFont
@@ -1345,7 +1423,7 @@ CairoRenderContext::renderGlyphtext(PangoFont *font, NRMatrix const *font_matrix
cairo_save(_cr);
-#ifndef PANGO_ENABLE_BACKEND
+#ifdef CAIRO_HAS_FT_FONT
cairo_font_face_t *font_face = cairo_ft_font_face_create_for_pattern(fc_pattern);
cairo_set_font_face(_cr, font_face);
@@ -1364,25 +1442,21 @@ CairoRenderContext::renderGlyphtext(PangoFont *font, NRMatrix const *font_matrix
} else {
cairo_set_fill_rule(_cr, CAIRO_FILL_RULE_WINDING);
}
- cairo_set_source_rgba (_cr, 1.0, 1.0, 1.0, 1.0);
- cairo_rectangle (_cr, 0, 0, 30, 40);
- cairo_fill (_cr);
_showGlyphs(_cr, font, glyphtext, FALSE);
- //cairo_fill(_cr);
} else {
// just add the glyph paths to the current context
_showGlyphs(_cr, font, glyphtext, TRUE);
}
} else {
- if (style->fill.type == SP_PAINT_TYPE_COLOR || style->fill.type == SP_PAINT_TYPE_PAINTSERVER) {
+ if (style->fill.isColor() || style->fill.isPaintserver()) {
// set fill style
_setFillStyle(style, NULL);
_showGlyphs(_cr, font, glyphtext, FALSE);
}
- if (style->stroke.type == SP_PAINT_TYPE_COLOR || style->stroke.type == SP_PAINT_TYPE_PAINTSERVER) {
+ if (style->stroke.isColor() || style->stroke.isPaintserver()) {
// set stroke style
_setStrokeStyle(style, NULL);
@@ -1398,6 +1472,8 @@ CairoRenderContext::renderGlyphtext(PangoFont *font, NRMatrix const *font_matrix
#else
(void)size;
(void)fc_pattern;
+
+ cairo_restore(_cr);
#endif
return true;
@@ -1459,7 +1535,7 @@ CairoRenderContext::_concatTransform(cairo_t *cr, double xx, double yx, double x
}
void
-CairoRenderContext::_initCairoMatrix(cairo_matrix_t *matrix, NRMatrix const *transform)
+CairoRenderContext::_initCairoMatrix(cairo_matrix_t *matrix, NR::Matrix const *transform)
{
matrix->xx = (*transform)[0];
matrix->yx = (*transform)[1];
@@ -1470,7 +1546,7 @@ CairoRenderContext::_initCairoMatrix(cairo_matrix_t *matrix, NRMatrix const *tra
}
void
-CairoRenderContext::_concatTransform(cairo_t *cr, NRMatrix const *transform)
+CairoRenderContext::_concatTransform(cairo_t *cr, NR::Matrix const *transform)
{
_concatTransform(cr, (*transform)[0], (*transform)[1],
(*transform)[2], (*transform)[3],
@@ -1502,8 +1578,6 @@ _write_callback(void *closure, const unsigned char *data, unsigned int length)
/* End of GNU GPL code */
-#endif /* HAVE_CAIRO_PDF */
-
/*
Local Variables: