void FontPlatformData::initializeWithFontFace(cairo_font_face_t* fontFace, const FontDescription& fontDescription) { cairo_font_options_t* options = getDefaultFontOptions(); cairo_matrix_t ctm; cairo_matrix_init_identity(&ctm); // Scaling a font with width zero size leads to a failed cairo_scaled_font_t instantiations. // Instead we scale we scale the font to a very tiny size and just abort rendering later on. float realSize = m_size ? m_size : 1; cairo_matrix_t fontMatrix; if (!m_pattern) cairo_matrix_init_scale(&fontMatrix, realSize, realSize); else { setCairoFontOptionsFromFontConfigPattern(options, m_pattern.get()); // FontConfig may return a list of transformation matrices with the pattern, for instance, // for fonts that are oblique. We use that to initialize the cairo font matrix. FcMatrix fontConfigMatrix, *tempFontConfigMatrix; FcMatrixInit(&fontConfigMatrix); // These matrices may be stacked in the pattern, so it's our job to get them all and multiply them. for (int i = 0; FcPatternGetMatrix(m_pattern.get(), FC_MATRIX, i, &tempFontConfigMatrix) == FcResultMatch; i++) FcMatrixMultiply(&fontConfigMatrix, &fontConfigMatrix, tempFontConfigMatrix); cairo_matrix_init(&fontMatrix, fontConfigMatrix.xx, -fontConfigMatrix.yx, -fontConfigMatrix.xy, fontConfigMatrix.yy, 0, 0); // We requested an italic font, but Fontconfig gave us one that was neither oblique nor italic. int actualFontSlant; if (fontDescription.italic() && FcPatternGetInteger(m_pattern.get(), FC_SLANT, 0, &actualFontSlant) == FcResultMatch) m_syntheticOblique = actualFontSlant == FC_SLANT_ROMAN; // The matrix from FontConfig does not include the scale. cairo_matrix_scale(&fontMatrix, realSize, realSize); } if (syntheticOblique()) { static const float syntheticObliqueSkew = -tanf(14 * acosf(0) / 90); cairo_matrix_t skew = {1, 0, syntheticObliqueSkew, 1, 0, 0}; cairo_matrix_multiply(&fontMatrix, &skew, &fontMatrix); } m_horizontalOrientationMatrix = fontMatrix; if (m_orientation == Vertical) rotateCairoMatrixForVerticalOrientation(&fontMatrix); m_scaledFont = cairo_scaled_font_create(fontFace, &fontMatrix, &ctm, options); cairo_font_options_destroy(options); }
static PyObject * matrix_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { static char *kwlist[] = { "xx", "yx", "xy", "yy", "x0", "y0", NULL }; double xx = 1.0, yx = 0.0, xy = 0.0, yy = 1.0, x0 = 0.0, y0 = 0.0; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|dddddd:Matrix.__init__", kwlist, &xx, &yx, &xy, &yy, &x0, &y0)) return NULL; cairo_matrix_t mx; cairo_matrix_init (&mx, xx, yx, xy, yy, x0, y0); return PycairoMatrix_FromMatrix (&mx); }
static void rsvg_cairo_clip_apply_affine (RsvgCairoClipRender *render, cairo_matrix_t *affine) { RsvgCairoRender *cairo_render = &render->super; cairo_matrix_t matrix; gboolean nest = cairo_render->cr != cairo_render->initial_cr; cairo_matrix_init (&matrix, affine->xx, affine->yx, affine->xy, affine->yy, affine->x0 + (nest ? 0 : render->parent->offset_x), affine->y0 + (nest ? 0 : render->parent->offset_y)); cairo_set_matrix (cairo_render->cr, &matrix); }
static void cmd_flip_x (struct document *doc) { int width = (doc->flags & NO_GENERIC_SCALE) ? doc->width : ceil(doc->scale * doc->width); cairo_matrix_t flipx; cairo_matrix_init (&flipx, -1, 0, 0, 1, width, 0); /* * .y y. * │ -> │ * └─x x─┘ */ cairo_matrix_multiply (&doc->transform, &doc->transform, &flipx); }
void Drawer::RotationOLD(double aAngle) { mAngle = aAngle * M_PI / 180; double CentreX = 0.0; double CentreY = 0.0; cairo_matrix_t Matrice; cairo_get_current_point(mCairoDC, &CentreX, &CentreY); cairo_matrix_init (&Matrice, cos (mAngle), sin (mAngle), -sin (mAngle), cos(mAngle), CentreX * (1 - cos (mAngle)) + sin (mAngle) * CentreY, CentreY * ( 1 - cos (mAngle)) - sin (mAngle) * CentreX); cairo_transform (mCairoDC, &Matrice); }
void dtgtk_cairo_paint_solid_triangle(cairo_t *cr, gint x,int y,gint w,gint h, gint flags) { /* initialize rotation and flip matrices */ cairo_matrix_t hflip_matrix; cairo_matrix_init(&hflip_matrix,-1,0,0,1,1,0); double C=cos(-(M_PI/2.0)),S=sin(-(M_PI/2.0)); // -90 degrees C=flags&CPF_DIRECTION_DOWN?cos(-(M_PI*1.5)):C; S=flags&CPF_DIRECTION_DOWN?sin(-(M_PI*1.5)):S; cairo_matrix_t rotation_matrix; cairo_matrix_init(&rotation_matrix,C,S,-S,C,0.5-C*0.5+S*0.5,0.5-S*0.5-C*0.5); /* scale and transform*/ gint s=w<h?w:h; cairo_translate(cr, x+(w/2.0)-(s/2.0), y+(h/2.0)-(s/2.0)); cairo_scale(cr,s,s); cairo_set_line_width(cr,0.1); cairo_set_line_cap(cr,CAIRO_LINE_CAP_ROUND); if( flags&CPF_DIRECTION_UP || flags &CPF_DIRECTION_DOWN) cairo_transform(cr,&rotation_matrix); else if(flags&CPF_DIRECTION_LEFT) // Flip x transformation cairo_transform(cr,&hflip_matrix); cairo_move_to(cr, 0.2, 0.2); cairo_line_to(cr, 0.7, 0.5); cairo_line_to(cr, 0.2, 0.8); cairo_line_to(cr, 0.2, 0.2); cairo_stroke(cr); cairo_move_to(cr, 0.2, 0.2); cairo_line_to(cr, 0.7, 0.5); cairo_line_to(cr, 0.2, 0.8); cairo_line_to(cr, 0.2, 0.2); cairo_fill(cr); cairo_identity_matrix(cr); }
/** * cairo_matrix_init_rotate: * @matrix: a #cairo_matrix_t * @radians: angle of rotation, in radians. The direction of rotation * is defined such that positive angles rotate in the direction from * the positive X axis toward the positive Y axis. With the default * axis orientation of cairo, positive angles rotate in a clockwise * direction. * * Initialized @matrix to a transformation that rotates by @radians. **/ void cairo_matrix_init_rotate (cairo_matrix_t *matrix, double radians) { double s; double c; s = sin (radians); c = cos (radians); cairo_matrix_init (matrix, c, s, -s, c, 0, 0); }
/*! \todo Finish function documentation!!! * \brief * \par Function Description * */ int o_text_get_rendered_bounds (void *user_data, OBJECT *o_current, int *min_x, int *min_y, int *max_x, int *max_y) { GschemToplevel *w_current = (GschemToplevel *) user_data; TOPLEVEL *toplevel; EdaRenderer *renderer; cairo_t *cr; cairo_matrix_t render_mtx; int result, render_flags = 0; double t, l, r, b; g_return_val_if_fail ((w_current != NULL), FALSE); toplevel = gschem_toplevel_get_toplevel (w_current); cr = gdk_cairo_create (w_current->drawable); /* Set up renderer based on configuration in w_current. Note that we * *don't* enable hinting, because if its enabled the calculated * bounds are zoom-level-dependent. */ if (toplevel->show_hidden_text) render_flags |= EDA_RENDERER_FLAG_TEXT_HIDDEN; renderer = g_object_ref (w_current->renderer); g_object_set (G_OBJECT (renderer), "cairo-context", cr, "render-flags", render_flags, NULL); /* We need to transform the cairo context to approximate world * coordinates. */ cairo_matrix_init (&render_mtx, 1, 0, 0, -1, -1, 1); cairo_set_matrix (cr, &render_mtx); /* Use the renderer to calculate text bounds */ result = eda_renderer_get_user_bounds (renderer, o_current, &l, &t, &r, &b); /* Clean up */ eda_renderer_destroy (renderer); cairo_destroy (cr); /* Round bounds to nearest integer */ *min_x = lrint (fmin (l, r)); *min_y = lrint (fmin (t, b)); *max_x = lrint (fmax (l, r)); *max_y = lrint (fmax (t, b)); return result; }
static cairo_pattern_t * _pattern_build_for_cairo (DiaPattern *pattern, const Rectangle *ext) { cairo_pattern_t *pat; gsize i; real x, y; DiaPatternType type; guint flags; Point p1, p2; real r; g_return_val_if_fail (pattern != NULL, NULL); dia_pattern_get_settings (pattern, &type, &flags); dia_pattern_get_points (pattern, &p1, &p2); dia_pattern_get_radius (pattern, &r); switch (type ) { case DIA_LINEAR_GRADIENT : pat = cairo_pattern_create_linear (p1.x, p1.y, p2.x, p2.y); break; case DIA_RADIAL_GRADIENT : pat = cairo_pattern_create_radial (p2.x, p2.y, 0.0, p1.x, p1.y, r); break; default : g_warning ("_pattern_build_for_cairo non such."); return NULL; } /* this must only be optionally done */ if ((flags & DIA_PATTERN_USER_SPACE)==0) { cairo_matrix_t matrix; real w = ext->right - ext->left; real h = ext->bottom - ext->top; cairo_matrix_init (&matrix, w, 0.0, 0.0, h, ext->left, ext->top); cairo_matrix_invert (&matrix); cairo_pattern_set_matrix (pat, &matrix); } if (flags & DIA_PATTERN_EXTEND_PAD) cairo_pattern_set_extend (pat, CAIRO_EXTEND_PAD); else if (flags & DIA_PATTERN_EXTEND_REPEAT) cairo_pattern_set_extend (pat, CAIRO_EXTEND_REPEAT); else if (flags & DIA_PATTERN_EXTEND_REFLECT) cairo_pattern_set_extend (pat, CAIRO_EXTEND_REFLECT); dia_pattern_foreach (pattern, _add_color_stop, pat); return pat; }
/* This function isn't a correct adjoint in that the implicit 1 in the homogeneous result should actually be ad-bc instead. But, since this adjoint is only used in the computation of the inverse, which divides by det (A)=ad-bc anyway, everything works out in the end. */ static void _cairo_matrix_compute_adjoint (cairo_matrix_t *matrix) { /* adj (A) = transpose (C:cofactor (A,i,j)) */ double a, b, c, d, tx, ty; _cairo_matrix_get_affine (matrix, &a, &b, &c, &d, &tx, &ty); cairo_matrix_init (matrix, d, -b, -c, a, c*ty - d*tx, b*tx - a*ty); }
static void cmd_flip_y (struct document *doc) { int height = (doc->flags & NO_GENERIC_SCALE) ? doc->height : ceil(doc->scale * doc->height); cairo_matrix_t flipy; cairo_matrix_init (&flipy, 1, 0, 0, -1, 0, height); /* .y . * │ * └─x -> * ┌─x * │ * y */ cairo_matrix_multiply (&doc->transform, &doc->transform, &flipy); }
static void do_drawing(cairo_t *cr) { cairo_matrix_t matrix; cairo_set_source_rgb(cr, 0.6, 0.6, 0.6); cairo_rectangle(cr, 20, 30, 80, 50); cairo_fill(cr); cairo_matrix_init(&matrix, 1.0, 0.5, 0.0, 1.0, 0.0, 0.0 ); cairo_transform(cr, &matrix); cairo_rectangle(cr, 130, 30, 80, 50); cairo_fill(cr); }
HBITMAP allocImage(HDC dc, IntSize size, CairoContextRef* targetRef) { BITMAPINFO bmpInfo = {0}; bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmpInfo.bmiHeader.biWidth = size.width(); bmpInfo.bmiHeader.biHeight = size.height(); // Must be positive! bmpInfo.bmiHeader.biPlanes = 1; bmpInfo.bmiHeader.biBitCount = 32; bmpInfo.bmiHeader.biCompression = BI_RGB; bmpInfo.bmiHeader.biClrUsed = 0; // unused bmpInfo.bmiHeader.biClrImportant = 0; LPVOID bits; HBITMAP hbmp = CreateDIBSection(dc, &bmpInfo, DIB_RGB_COLORS, &bits, 0, 0); // At this point, we have a Cairo surface that points to a Windows DIB. The DIB interprets // with the opposite meaning of positive Y axis, so everything we draw into this cairo // context is going to be upside down. if (!targetRef) return hbmp; cairo_surface_t* bitmapContext = cairo_image_surface_create_for_data((unsigned char*)bits, CAIRO_FORMAT_ARGB32, bmpInfo.bmiHeader.biWidth, bmpInfo.bmiHeader.biHeight, bmpInfo.bmiHeader.biWidth * 4); if (!bitmapContext) { DeleteObject(hbmp); return 0; } *targetRef = cairo_create (bitmapContext); cairo_surface_destroy (bitmapContext); // At this point, we have a Cairo surface that points to a Windows DIB. The DIB interprets // with the opposite meaning of positive Y axis, so everything we draw into this cairo // context is going to be upside down. // // So, we must invert the CTM for the context so that drawing commands will be flipped // before they get written to the internal buffer. cairo_matrix_t matrix; cairo_matrix_init(&matrix, 1.0, 0.0, 0.0, -1.0, 0.0, size.height()); cairo_set_matrix(*targetRef, &matrix); return hbmp; }
static cairo_int_status_t _paint_fallback_image (cairo_paginated_surface_t *surface, cairo_rectangle_int_t *rect) { double x_scale = surface->base.x_fallback_resolution / surface->target->x_resolution; double y_scale = surface->base.y_fallback_resolution / surface->target->y_resolution; int x, y, width, height; cairo_status_t status; cairo_surface_t *image; cairo_surface_pattern_t pattern; cairo_clip_t *clip; x = rect->x; y = rect->y; width = rect->width; height = rect->height; image = _cairo_paginated_surface_create_image_surface (surface, ceil (width * x_scale), ceil (height * y_scale)); _cairo_surface_set_device_scale (image, x_scale, y_scale); /* set_device_offset just sets the x0/y0 components of the matrix; * so we have to do the scaling manually. */ cairo_surface_set_device_offset (image, -x*x_scale, -y*y_scale); status = _cairo_recording_surface_replay (surface->recording_surface, image); if (unlikely (status)) goto CLEANUP_IMAGE; _cairo_pattern_init_for_surface (&pattern, image); cairo_matrix_init (&pattern.base.matrix, x_scale, 0, 0, y_scale, -x*x_scale, -y*y_scale); /* the fallback should be rendered at native resolution, so disable * filtering (if possible) to avoid introducing potential artifacts. */ pattern.base.filter = CAIRO_FILTER_NEAREST; clip = _cairo_clip_intersect_rectangle (NULL, rect); status = _cairo_surface_paint (surface->target, CAIRO_OPERATOR_SOURCE, &pattern.base, clip); _cairo_clip_destroy (clip); _cairo_pattern_fini (&pattern.base); CLEANUP_IMAGE: cairo_surface_destroy (image); return (cairo_int_status_t)status; }
static void matrix_init(cairo_matrix_t *mat, double width, double height, OGREnvelope *bounds){ cairo_matrix_init(mat, 1, 0, 0, -1, 0, 0); cairo_matrix_translate(mat, 0, height * -1.0); double w, bWidth = fabs(bounds->MaxX - bounds->MinX), bHeight = fabs(bounds->MaxY - bounds->MinY); if(bWidth > bHeight){ w = width / bWidth; } else { w = height / bHeight; } cairo_matrix_scale(mat, w, w); cairo_matrix_translate(mat, -bounds->MinX, -bounds->MinY); }
/** * goo_canvas_item_model_skew_y: * @model: an item model. * @degrees: the skew angle. * @cx: the x coordinate of the origin of the skew transform. * @cy: the y coordinate of the origin of the skew transform. * * Skews the model's coordinate system along the y axis by the given amount, * about the given origin. **/ void goo_canvas_item_model_skew_y (GooCanvasItemModel *model, gdouble degrees, gdouble cx, gdouble cy) { GooCanvasItemModelIface *iface = GOO_CANVAS_ITEM_MODEL_GET_IFACE (model); cairo_matrix_t tmp, new_matrix = { 1, 0, 0, 1, 0, 0 }; double radians = degrees * (M_PI / 180); iface->get_transform (model, &new_matrix); cairo_matrix_translate (&new_matrix, cx, cy); cairo_matrix_init (&tmp, 1, tan (radians), 0, 1, 0, 0); cairo_matrix_multiply (&new_matrix, &tmp, &new_matrix); cairo_matrix_translate (&new_matrix, -cx, -cy); iface->set_transform (model, &new_matrix); }
static PyObject * matrix_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *o; static char *kwlist[] = { "xx", "yx", "xy", "yy", "x0", "y0", NULL }; double xx = 1.0, yx = 0.0, xy = 0.0, yy = 1.0, x0 = 0.0, y0 = 0.0; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|dddddd:Matrix.__init__", kwlist, &xx, &yx, &xy, &yy, &x0, &y0)) return NULL; o = type->tp_alloc(type, 0); if (o) cairo_matrix_init (&((PycairoMatrix *)o)->matrix, xx, yx, xy, yy, x0, y0); return o; }
void cairo_context::add_image(agg::trans_affine const& tr, image_rgba8 const& data, double opacity) { cairo_pattern pattern(data); if (!tr.is_identity()) { double m[6]; tr.store_to(m); cairo_matrix_t cairo_matrix; cairo_matrix_init(&cairo_matrix,m[0],m[1],m[2],m[3],m[4],m[5]); cairo_matrix_invert(&cairo_matrix); pattern.set_matrix(cairo_matrix); } cairo_save(cairo_.get()); cairo_set_source(cairo_.get(), const_cast<cairo_pattern_t*>(pattern.pattern())); cairo_paint_with_alpha(cairo_.get(), opacity); cairo_restore(cairo_.get()); check_object_status_and_throw_exception(*this); }
cairo_scaled_font_t * gfxDWriteFont::CairoScaledFont() { if (!mCairoScaledFont) { cairo_matrix_t sizeMatrix; cairo_matrix_t identityMatrix; cairo_matrix_init_scale(&sizeMatrix, mAdjustedSize, mAdjustedSize); cairo_matrix_init_identity(&identityMatrix); cairo_font_options_t *fontOptions = cairo_font_options_create(); if (mNeedsOblique) { double skewfactor = OBLIQUE_SKEW_FACTOR; cairo_matrix_t style; cairo_matrix_init(&style, 1, //xx 0, //yx -1 * skewfactor, //xy 1, //yy 0, //x0 0); //y0 cairo_matrix_multiply(&sizeMatrix, &sizeMatrix, &style); } if (mAntialiasOption != kAntialiasDefault) { cairo_font_options_set_antialias(fontOptions, GetCairoAntialiasOption(mAntialiasOption)); } mCairoScaledFont = cairo_scaled_font_create(CairoFontFace(), &sizeMatrix, &identityMatrix, fontOptions); cairo_font_options_destroy(fontOptions); } NS_ASSERTION(mAdjustedSize == 0.0 || cairo_scaled_font_status(mCairoScaledFont) == CAIRO_STATUS_SUCCESS, "Failed to make scaled font"); return mCairoScaledFont; }
void _pango_cairo_font_private_initialize (PangoCairoFontPrivate *cf_priv, PangoCairoFont *cfont, PangoGravity gravity, const cairo_font_options_t *font_options, const PangoMatrix *pango_ctm, const cairo_matrix_t *font_matrix) { cairo_matrix_t gravity_matrix; cf_priv->cfont = cfont; cf_priv->gravity = gravity; cf_priv->data = _pango_cairo_font_private_scaled_font_data_create (); /* first apply gravity rotation, then font_matrix, such that * vertical italic text comes out "correct". we don't do anything * like baseline adjustment etc though. should be specially * handled when we support italic correction. */ cairo_matrix_init_rotate(&gravity_matrix, pango_gravity_to_rotation (cf_priv->gravity)); cairo_matrix_multiply (&cf_priv->data->font_matrix, font_matrix, &gravity_matrix); if (pango_ctm) cairo_matrix_init (&cf_priv->data->ctm, pango_ctm->xx, pango_ctm->yx, pango_ctm->xy, pango_ctm->yy, 0., 0.); else cairo_matrix_init_identity (&cf_priv->data->ctm); cf_priv->data->options = cairo_font_options_copy (font_options); cf_priv->is_hinted = cairo_font_options_get_hint_metrics (font_options) != CAIRO_HINT_METRICS_OFF; cf_priv->scaled_font = NULL; cf_priv->hbi = NULL; cf_priv->glyph_extents_cache = NULL; cf_priv->metrics_by_lang = NULL; }
HBITMAP allocImage(HDC dc, IntSize size, PlatformContextCairo** targetRef) { BitmapInfo bmpInfo = BitmapInfo::create(size); LPVOID bits; HBITMAP hbmp = CreateDIBSection(dc, &bmpInfo, DIB_RGB_COLORS, &bits, 0, 0); // At this point, we have a Cairo surface that points to a Windows DIB. The DIB interprets // with the opposite meaning of positive Y axis, so everything we draw into this cairo // context is going to be upside down. if (!targetRef) return hbmp; cairo_surface_t* bitmapContext = cairo_image_surface_create_for_data((unsigned char*)bits, CAIRO_FORMAT_ARGB32, bmpInfo.bmiHeader.biWidth, bmpInfo.bmiHeader.biHeight, bmpInfo.bmiHeader.biWidth * 4); if (!bitmapContext) { DeleteObject(hbmp); return 0; } cairo_t* cr = cairo_create(bitmapContext); cairo_surface_destroy(bitmapContext); // At this point, we have a Cairo surface that points to a Windows DIB. The DIB interprets // with the opposite meaning of positive Y axis, so everything we draw into this cairo // context is going to be upside down. // // So, we must invert the CTM for the context so that drawing commands will be flipped // before they get written to the internal buffer. cairo_matrix_t matrix; cairo_matrix_init(&matrix, 1.0, 0.0, 0.0, -1.0, 0.0, size.height()); cairo_set_matrix(cr, &matrix); *targetRef = new PlatformGraphicsContext(cr); cairo_destroy(cr); return hbmp; }
static cairo_int_status_t _paint_fallback_image (cairo_paginated_surface_t *surface, cairo_box_int_t *box) { double x_scale = surface->base.x_fallback_resolution / surface->target->x_resolution; double y_scale = surface->base.y_fallback_resolution / surface->target->y_resolution; cairo_matrix_t matrix; int x, y, width, height; cairo_status_t status; cairo_surface_t *image; cairo_pattern_t *pattern; x = box->p1.x; y = box->p1.y; width = box->p2.x - x; height = box->p2.y - y; image = _cairo_paginated_surface_create_image_surface (surface, ceil (width * x_scale), ceil (height * y_scale)); _cairo_surface_set_device_scale (image, x_scale, y_scale); /* set_device_offset just sets the x0/y0 components of the matrix; * so we have to do the scaling manually. */ cairo_surface_set_device_offset (image, -x*x_scale, -y*y_scale); status = _cairo_meta_surface_replay (surface->meta, image); if (status) goto CLEANUP_IMAGE; pattern = cairo_pattern_create_for_surface (image); cairo_matrix_init (&matrix, x_scale, 0, 0, y_scale, -x*x_scale, -y*y_scale); cairo_pattern_set_matrix (pattern, &matrix); status = _cairo_surface_paint (surface->target, CAIRO_OPERATOR_SOURCE, pattern); cairo_pattern_destroy (pattern); CLEANUP_IMAGE: cairo_surface_destroy (image); return status; }
void rsvg_cairo_clip (RsvgDrawingCtx * ctx, RsvgClipPath * clip, RsvgBbox * bbox) { RsvgCairoClipRender *clip_render; RsvgCairoRender *save = RSVG_CAIRO_RENDER (ctx->render); cairo_t *cr; cairo_matrix_t affinesave; cr = save->cr; clip_render = RSVG_CAIRO_CLIP_RENDER (rsvg_cairo_clip_render_new (cr, save)); ctx->render = &clip_render->super.super; /* Horribly dirty hack to have the bbox premultiplied to everything */ if (clip->units == objectBoundingBox) { cairo_matrix_t bbtransform; cairo_matrix_init (&bbtransform, bbox->rect.width, 0, 0, bbox->rect.height, bbox->rect.x, bbox->rect.y); affinesave = clip->super.state->affine; cairo_matrix_multiply (&clip->super.state->affine, &bbtransform, &clip->super.state->affine); } rsvg_state_push (ctx); _rsvg_node_draw_children ((RsvgNode *) clip, ctx, 0); rsvg_state_pop (ctx); if (clip->units == objectBoundingBox) clip->super.state->affine = affinesave; g_assert (clip_render->super.cr_stack == NULL); g_assert (clip_render->super.bb_stack == NULL); g_assert (clip_render->super.surfaces_stack == NULL); g_free (ctx->render); cairo_clip (cr); ctx->render = &save->super; }
void FontPlatformData::initializeWithFontFace(cairo_font_face_t* fontFace) { cairo_font_options_t* options = 0; #if !PLATFORM(CLUTTER) && (!PLATFORM(EFL) || ENABLE(GLIB_SUPPORT)) if (GdkScreen* screen = gdk_screen_get_default()) options = cairo_font_options_copy(gdk_screen_get_font_options(screen)); #endif // gdk_screen_get_font_options() returns null if no default // options are set, so we always have to check. if (!options) options = cairo_font_options_create(); cairo_matrix_t ctm; cairo_matrix_init_identity(&ctm); cairo_matrix_t fontMatrix; if (!m_pattern) cairo_matrix_init_scale(&fontMatrix, m_size, m_size); else { setCairoFontOptionsFromFontConfigPattern(options, m_pattern.get()); // FontConfig may return a list of transformation matrices with the pattern, for instance, // for fonts that are oblique. We use that to initialize the cairo font matrix. FcMatrix fontConfigMatrix, *tempFontConfigMatrix; FcMatrixInit(&fontConfigMatrix); // These matrices may be stacked in the pattern, so it's our job to get them all and multiply them. for (int i = 0; FcPatternGetMatrix(m_pattern.get(), FC_MATRIX, i, &tempFontConfigMatrix) == FcResultMatch; i++) FcMatrixMultiply(&fontConfigMatrix, &fontConfigMatrix, tempFontConfigMatrix); cairo_matrix_init(&fontMatrix, fontConfigMatrix.xx, -fontConfigMatrix.yx, -fontConfigMatrix.xy, fontConfigMatrix.yy, 0, 0); // The matrix from FontConfig does not include the scale. cairo_matrix_scale(&fontMatrix, m_size, m_size); } m_scaledFont = adoptPlatformRef(cairo_scaled_font_create(fontFace, &fontMatrix, &ctm, options)); cairo_font_options_destroy(options); }
void ge_cairo_exchange_axis (cairo_t *cr, gint *x, gint *y, gint *width, gint *height) { gint tmp; cairo_matrix_t matrix; cairo_translate (cr, *x, *y); cairo_matrix_init (&matrix, 0, 1, 1, 0, 0, 0); cairo_transform (cr, &matrix); /* swap width/height */ tmp = *width; *x = 0; *y = 0; *width = *height; *height = tmp; }
void GraphicsContext3D::paintToCanvas(const unsigned char* imagePixels, int imageWidth, int imageHeight, int canvasWidth, int canvasHeight, PlatformContextCairo* context) { if (!imagePixels || imageWidth <= 0 || imageHeight <= 0 || canvasWidth <= 0 || canvasHeight <= 0 || !context) return; cairo_t* cr = context->cr(); context->save(); RefPtr<cairo_surface_t> imageSurface = adoptRef(cairo_image_surface_create_for_data( const_cast<unsigned char*>(imagePixels), CAIRO_FORMAT_ARGB32, imageWidth, imageHeight, imageWidth * 4)); cairo_rectangle(cr, 0, 0, canvasWidth, canvasHeight); // OpenGL keeps the pixels stored bottom up, so we need to flip the image here. cairo_matrix_t matrix; cairo_matrix_init(&matrix, 1.0, 0.0, 0.0, -1.0, 0.0, imageHeight); cairo_set_matrix(cr, &matrix); cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); cairo_set_source_surface(cr, imageSurface.get(), 0, 0); cairo_fill(cr); context->restore(); }
static void prepare_context_for_layout (cairo_t *cr, gdouble x, gdouble y, PangoLayout *layout) { const PangoMatrix *matrix; matrix = pango_context_get_matrix (pango_layout_get_context (layout)); cairo_move_to (cr, x, y); if (matrix) { cairo_matrix_t cairo_matrix; cairo_matrix_init (&cairo_matrix, matrix->xx, matrix->yx, matrix->xy, matrix->yy, matrix->x0, matrix->y0); cairo_transform (cr, &cairo_matrix); } }
static void brush_end_element (GMarkupParseContext *context, const gchar *element_name, gpointer user_data, GError **error) { GXPSBrush *brush = (GXPSBrush *)user_data; if (strcmp (element_name, "SolidColorBrush") == 0) { } else if (strcmp (element_name, "LinearGradientBrush") == 0) { g_markup_parse_context_pop (context); } else if (strcmp (element_name, "RadialGradientBrush") == 0) { g_markup_parse_context_pop (context); } else if (strcmp (element_name, "ImageBrush") == 0) { GXPSBrushImage *brush_image; GXPSImage *image; GError *err = NULL; brush_image = g_markup_parse_context_pop (context); GXPS_DEBUG (g_message ("set_fill_pattern (image)")); image = gxps_page_get_image (brush->ctx->page, brush_image->image_uri, &err); if (image) { cairo_matrix_t matrix; gdouble x_scale, y_scale; cairo_surface_t *clip_surface; /* viewbox units is 1/96 inch, convert to pixels */ brush_image->viewbox.x *= image->res_x / 96; brush_image->viewbox.y *= image->res_y / 96; brush_image->viewbox.width *= image->res_x / 96; brush_image->viewbox.height *= image->res_y / 96; clip_surface = cairo_surface_create_for_rectangle (image->surface, brush_image->viewbox.x, brush_image->viewbox.y, brush_image->viewbox.width, brush_image->viewbox.height); brush_image->brush->pattern = cairo_pattern_create_for_surface (clip_surface); cairo_pattern_set_extend (brush_image->brush->pattern, brush_image->extend); x_scale = brush_image->viewport.width / brush_image->viewbox.width; y_scale = brush_image->viewport.height / brush_image->viewbox.height; cairo_matrix_init (&matrix, x_scale, 0, 0, y_scale, brush_image->viewport.x, brush_image->viewport.y); cairo_matrix_multiply (&matrix, &matrix, &brush_image->matrix); cairo_matrix_invert (&matrix); cairo_pattern_set_matrix (brush_image->brush->pattern, &matrix); if (brush->opacity != 1.0) { cairo_push_group (brush->ctx->cr); cairo_set_source (brush->ctx->cr, brush_image->brush->pattern); cairo_pattern_destroy (brush_image->brush->pattern); cairo_paint_with_alpha (brush->ctx->cr, brush->opacity); brush_image->brush->pattern = cairo_pop_group (brush->ctx->cr); } if (cairo_pattern_status (brush_image->brush->pattern)) { GXPS_DEBUG (g_debug ("%s", cairo_status_to_string (cairo_pattern_status (brush_image->brush->pattern)))); cairo_pattern_destroy (brush_image->brush->pattern); brush_image->brush->pattern = NULL; } cairo_surface_destroy (clip_surface); } else if (err) { GXPS_DEBUG (g_debug ("%s", err->message)); g_error_free (err); } gxps_brush_image_free (brush_image); } else if (strcmp (element_name, "VisualBrush") == 0) { GXPSRenderContext *sub_ctx; GXPSBrushVisual *visual; cairo_matrix_t matrix; sub_ctx = g_markup_parse_context_pop (context); visual = sub_ctx->visual; g_slice_free (GXPSRenderContext, sub_ctx); GXPS_DEBUG (g_message ("set_fill_pattern (visual)")); visual->brush->pattern = cairo_pop_group (brush->ctx->cr); /* Undo the clip */ cairo_restore (brush->ctx->cr); cairo_pattern_set_extend (visual->brush->pattern, visual->extend); cairo_pattern_get_matrix (visual->brush->pattern, &matrix); cairo_matrix_multiply (&matrix, &visual->matrix, &matrix); cairo_pattern_set_matrix (visual->brush->pattern, &matrix); if (cairo_pattern_status (visual->brush->pattern)) { GXPS_DEBUG (g_debug ("%s", cairo_status_to_string (cairo_pattern_status (visual->brush->pattern)))); cairo_pattern_destroy (visual->brush->pattern); visual->brush->pattern = NULL; } gxps_brush_visual_free (visual); } else { gxps_parse_error (context, brush->ctx->page->priv->source, G_MARKUP_ERROR_UNKNOWN_ELEMENT, element_name, NULL, NULL, error); } }
static void brush_start_element (GMarkupParseContext *context, const gchar *element_name, const gchar **names, const gchar **values, gpointer user_data, GError **error) { GXPSBrush *brush = (GXPSBrush *)user_data; if (strcmp (element_name, "SolidColorBrush") == 0) { const gchar *color_str = NULL; gint i; for (i = 0; names[i] != NULL; i++) { if (strcmp (names[i], "Color") == 0) { color_str = values[i]; } else if (strcmp (names[i], "Opacity") == 0) { if (!gxps_value_get_double (values[i], &brush->opacity)) { gxps_parse_error (context, brush->ctx->page->priv->source, G_MARKUP_ERROR_INVALID_CONTENT, "SolidColorBrush", "Opacity", values[i], error); return; } } else { gxps_parse_error (context, brush->ctx->page->priv->source, G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, "SolidColorBrush", names[i], NULL, error); return; } } if (!color_str) { gxps_parse_error (context, brush->ctx->page->priv->source, G_MARKUP_ERROR_MISSING_ATTRIBUTE, "SolidColorBrush", "Color", NULL, error); return; } GXPS_DEBUG (g_message ("set_fill_pattern (solid)")); if (!gxps_brush_solid_color_parse (color_str, brush->ctx->page->priv->zip, brush->opacity, &brush->pattern)) { gxps_parse_error (context, brush->ctx->page->priv->source, G_MARKUP_ERROR_INVALID_CONTENT, "SolidColorBrush", "Color", color_str, error); return; } } else if (strcmp (element_name, "ImageBrush") == 0) { GXPSBrushImage *image; gchar *image_source = NULL; cairo_rectangle_t viewport = { 0, }, viewbox = { 0, }; cairo_matrix_t matrix; cairo_extend_t extend = CAIRO_EXTEND_NONE; gint i; cairo_matrix_init_identity (&matrix); for (i = 0; names[i] != NULL; i++) { if (strcmp (names[i], "ImageSource") == 0) { image_source = gxps_resolve_relative_path (brush->ctx->page->priv->source, values[i]); } else if (strcmp (names[i], "Transform") == 0) { if (!gxps_matrix_parse (values[i], &matrix)) { gxps_parse_error (context, brush->ctx->page->priv->source, G_MARKUP_ERROR_INVALID_CONTENT, "ImageBrush", "Transform", values[i], error); return; } } else if (strcmp (names[i], "Viewport") == 0) { if (!gxps_box_parse (values[i], &viewport)) { gxps_parse_error (context, brush->ctx->page->priv->source, G_MARKUP_ERROR_INVALID_CONTENT, "ImageBrush", "Viewport", values[i], error); return; } } else if (strcmp (names[i], "ViewportUnits") == 0) { } else if (strcmp (names[i], "Viewbox") == 0) { if (!gxps_box_parse (values[i], &viewbox)) { gxps_parse_error (context, brush->ctx->page->priv->source, G_MARKUP_ERROR_INVALID_CONTENT, "ImageBrush", "Viewbox", values[i], error); return; } } else if (strcmp (names[i], "ViewboxUnits") == 0) { } else if (strcmp (names[i], "TileMode") == 0) { extend = gxps_tile_mode_parse (values[i]); } else if (strcmp (names[i], "Opacity") == 0) { if (!gxps_value_get_double (values[i], &brush->opacity)) { gxps_parse_error (context, brush->ctx->page->priv->source, G_MARKUP_ERROR_INVALID_CONTENT, "ImageBrush", "Opacity", values[i], error); return; } } else { gxps_parse_error (context, brush->ctx->page->priv->source, G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, "ImageBrush", names[i], NULL, error); return; } } if (!image_source) { gxps_parse_error (context, brush->ctx->page->priv->source, G_MARKUP_ERROR_MISSING_ATTRIBUTE, element_name, "ImageSource", NULL, error); return; } /* GXPSBrushImage takes ownership of image_source */ image = gxps_brush_image_new (brush, image_source, &viewport, &viewbox); image->extend = extend; image->matrix = matrix; g_markup_parse_context_push (context, &brush_image_parser, image); } else if (strcmp (element_name, "LinearGradientBrush") == 0) { gint i; gdouble x0, y0, x1, y1; cairo_extend_t extend = CAIRO_EXTEND_PAD; cairo_matrix_t matrix; x0 = y0 = x1 = y1 = -1; cairo_matrix_init_identity (&matrix); for (i = 0; names[i] != NULL; i++) { if (strcmp (names[i], "MappingMode") == 0) { } else if (strcmp (names[i], "StartPoint") == 0) { if (!gxps_point_parse (values[i], &x0, &y0)) { gxps_parse_error (context, brush->ctx->page->priv->source, G_MARKUP_ERROR_INVALID_CONTENT, "LinearGradientBrush", "StartPoint", values[i], error); return; } } else if (strcmp (names[i], "EndPoint") == 0) { if (!gxps_point_parse (values[i], &x1, &y1)) { gxps_parse_error (context, brush->ctx->page->priv->source, G_MARKUP_ERROR_INVALID_CONTENT, "LinearGradientBrush", "EndPoint", values[i], error); return; } } else if (strcmp (names[i], "SpreadMethod") == 0) { extend = gxps_spread_method_parse (values[i]); } else if (strcmp (names[i], "Opacity") == 0) { if (!gxps_value_get_double (values[i], &brush->opacity)) { gxps_parse_error (context, brush->ctx->page->priv->source, G_MARKUP_ERROR_INVALID_CONTENT, "LinearGradientBrush", "Opacity", values[i], error); return; } } else if (strcmp (names[i], "Transform") == 0) { if (!gxps_matrix_parse (values[i], &matrix)) { gxps_parse_error (context, brush->ctx->page->priv->source, G_MARKUP_ERROR_INVALID_CONTENT, "LinearGradientBrush", "Transform", values[i], error); return; } } else if (strcmp (names[i], "ColorInterpolationMode") == 0) { GXPS_DEBUG (g_debug ("Unsupported %s attribute: ColorInterpolationMode", element_name)); } else { gxps_parse_error (context, brush->ctx->page->priv->source, G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, element_name, names[i], NULL, error); return; } } if (x0 == -1 || y0 == -1 || x1 == -1 || y1 == -1) { gxps_parse_error (context, brush->ctx->page->priv->source, G_MARKUP_ERROR_MISSING_ATTRIBUTE, element_name, (x0 == -1 || y0 == -1) ? "StartPoint" : "EndPoint", NULL, error); return; } GXPS_DEBUG (g_message ("set_fill_pattern (linear)")); brush->pattern = cairo_pattern_create_linear (x0, y0, x1, y1); cairo_pattern_set_matrix (brush->pattern, &matrix); cairo_pattern_set_extend (brush->pattern, extend); g_markup_parse_context_push (context, &brush_gradient_parser, brush); } else if (strcmp (element_name, "RadialGradientBrush") == 0) { gint i; gdouble cx0, cy0, r0, cx1, cy1, r1; cairo_extend_t extend = CAIRO_EXTEND_PAD; cairo_matrix_t matrix; cx0 = cy0 = r0 = cx1 = cy1 = r1 = -1; cairo_matrix_init_identity (&matrix); for (i = 0; names[i] != NULL; i++) { if (strcmp (names[i], "MappingMode") == 0) { } else if (strcmp (names[i], "GradientOrigin") == 0) { if (!gxps_point_parse (values[i], &cx0, &cy0)) { gxps_parse_error (context, brush->ctx->page->priv->source, G_MARKUP_ERROR_INVALID_CONTENT, "RadialGradientBrush", "GradientOrigin", values[i], error); return; } } else if (strcmp (names[i], "Center") == 0) { if (!gxps_point_parse (values[i], &cx1, &cy1)) { gxps_parse_error (context, brush->ctx->page->priv->source, G_MARKUP_ERROR_INVALID_CONTENT, "RadialGradientBrush", "Center", values[i], error); return; } } else if (strcmp (names[i], "RadiusX") == 0) { if (!gxps_value_get_double (values[i], &r0)) { gxps_parse_error (context, brush->ctx->page->priv->source, G_MARKUP_ERROR_INVALID_CONTENT, "RadialGradientBrush", "RadiusX", values[i], error); return; } } else if (strcmp (names[i], "RadiusY") == 0) { if (!gxps_value_get_double (values[i], &r1)) { gxps_parse_error (context, brush->ctx->page->priv->source, G_MARKUP_ERROR_INVALID_CONTENT, "RadialGradientBrush", "RadiusY", values[i], error); return; } } else if (strcmp (names[i], "SpreadMethod") == 0) { extend = gxps_spread_method_parse (values[i]); } else if (strcmp (names[i], "Opacity") == 0) { if (!gxps_value_get_double (values[i], &brush->opacity)) { gxps_parse_error (context, brush->ctx->page->priv->source, G_MARKUP_ERROR_INVALID_CONTENT, "RadialGradientBrush", "Opacity", values[i], error); return; } } else if (strcmp (names[i], "Transform") == 0) { if (!gxps_matrix_parse (values[i], &matrix)) { gxps_parse_error (context, brush->ctx->page->priv->source, G_MARKUP_ERROR_INVALID_CONTENT, "RadialGradientBrush", "Transform", values[i], error); return; } } else if (strcmp (names[i], "ColorInterpolationMode") == 0) { GXPS_DEBUG (g_debug ("Unsupported %s attribute: ColorInterpolationMode", element_name)); } else { gxps_parse_error (context, brush->ctx->page->priv->source, G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, element_name, names[i], NULL, error); return; } } if (cx0 == -1 || cy0 == -1 || cx1 == -1 || cy1 == -1) { gxps_parse_error (context, brush->ctx->page->priv->source, G_MARKUP_ERROR_MISSING_ATTRIBUTE, element_name, (cx0 == -1 || cy0 == -1) ? "GradientOrigin" : "Center", NULL, error); return; } if (r0 == -1 || r1 == -1) { gxps_parse_error (context, brush->ctx->page->priv->source, G_MARKUP_ERROR_MISSING_ATTRIBUTE, element_name, (r0 == -1) ? "RadiusX" : "RadiusY", NULL, error); return; } GXPS_DEBUG (g_message ("set_fill_pattern (radial)")); brush->pattern = cairo_pattern_create_radial (cx0, cy0, 0, cx1, cy1, r1); cairo_pattern_set_matrix (brush->pattern, &matrix); cairo_pattern_set_extend (brush->pattern, extend); g_markup_parse_context_push (context, &brush_gradient_parser, brush); } else if (strcmp (element_name, "VisualBrush") == 0) { GXPSBrushVisual *visual; GXPSRenderContext *sub_ctx; cairo_rectangle_t viewport = { 0, }, viewbox = { 0, }; cairo_matrix_t matrix; cairo_extend_t extend = CAIRO_EXTEND_NONE; double width, height; gint i; cairo_matrix_init_identity (&matrix); for (i = 0; names[i] != NULL; i++) { if (strcmp (names[i], "TileMode") == 0) { extend = gxps_tile_mode_parse (values[i]); } else if (strcmp (names[i], "Transform") == 0) { if (!gxps_matrix_parse (values[i], &matrix)) { gxps_parse_error (context, brush->ctx->page->priv->source, G_MARKUP_ERROR_INVALID_CONTENT, "VisualBrush", "Transform", values[i], error); return; } } else if (strcmp (names[i], "Viewport") == 0) { if (!gxps_box_parse (values[i], &viewport)) { gxps_parse_error (context, brush->ctx->page->priv->source, G_MARKUP_ERROR_INVALID_CONTENT, "VisualBrush", "Viewport", values[i], error); return; } } else if (strcmp (names[i], "ViewportUnits") == 0) { } else if (strcmp (names[i], "Viewbox") == 0) { if (!gxps_box_parse (values[i], &viewbox)) { gxps_parse_error (context, brush->ctx->page->priv->source, G_MARKUP_ERROR_INVALID_CONTENT, "VisualBrush", "Viewbox", values[i], error); return; } } else if (strcmp (names[i], "ViewboxUnits") == 0) { } else if (strcmp (names[i], "Opacity") == 0) { GXPS_DEBUG (g_debug ("Unsupported %s attribute: Opacity", element_name)); } else if (strcmp (names[i], "Visual") == 0) { GXPS_DEBUG (g_debug ("Unsupported %s attribute: Visual", element_name)); } else { gxps_parse_error (context, brush->ctx->page->priv->source, G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, element_name, names[i], NULL, error); return; } } /* TODO: check required values */ width = gxps_transform_hypot (&matrix, viewport.width, 0); height = gxps_transform_hypot (&matrix, 0, viewport.height); cairo_save (brush->ctx->cr); cairo_rectangle (brush->ctx->cr, 0, 0, width, height); cairo_clip (brush->ctx->cr); cairo_push_group (brush->ctx->cr); cairo_translate (brush->ctx->cr, -viewbox.x, -viewbox.y); cairo_scale (brush->ctx->cr, width / viewbox.width, height / viewbox.height); visual = gxps_brush_visual_new (brush, &viewport, &viewbox); visual->extend = extend; cairo_matrix_init (&visual->matrix, viewport.width / width, 0, 0, viewport.height / height, viewport.x, viewport.y); cairo_matrix_multiply (&visual->matrix, &visual->matrix, &matrix); cairo_matrix_invert (&visual->matrix); sub_ctx = g_slice_new0 (GXPSRenderContext); sub_ctx->page = brush->ctx->page; sub_ctx->cr = brush->ctx->cr; sub_ctx->visual = visual; gxps_page_render_parser_push (context, sub_ctx); } else { gxps_parse_error (context, brush->ctx->page->priv->source, G_MARKUP_ERROR_UNKNOWN_ELEMENT, element_name, NULL, NULL, error); } }
/*! \brief Draw a page. * \par Function Description * Draws the \a page on the Cairo context \a cr, which should have * dimensions \a cr_width and \a cr_height. If the Pango context \a * pc is provided, it is used for rendering of text. The parameter \a * is_color controls whether to enable color printing, and \a * is_raster should be set if drawing to a raster surface such as an * image. * * \param toplevel A #TOPLEVEL structure. * \param page The #PAGE to be rendered. * \param cr The Cairo context to render to. * \param pc A Pango context for text rendering, or NULL. * \param cr_width The width of the drawing area. * \param cr_height The height of the drawing area. * \param is_color TRUE if drawing should be in color; FALSE otherwise. * \param is_raster TRUE if drawing to a raster image surface; FALSE otherwise. */ static void x_print_draw_page (TOPLEVEL *toplevel, PAGE *page, cairo_t *cr, PangoContext *pc, double cr_width, double cr_height, gboolean is_color, gboolean is_raster) { EdaRenderer *renderer; cairo_matrix_t mtx; GArray *color_map; int status, wx_min, wy_min, wx_max, wy_max; double w_width, w_height, scale; GList *iter; /* First, calculate a transformation matrix for the cairo * context. We want to center the extents of the page in the * available page area. */ status = world_get_object_glist_bounds (toplevel, s_page_objects (page), &wx_min, &wy_min, &wx_max, &wy_max); /* If there are no printable objects, draw nothing. */ if (!status) return; w_width = wx_max - wx_min; w_height = wy_max - wy_min; scale = fmin (cr_width / w_width, cr_height / w_height); cairo_matrix_init (&mtx, scale, 0, 0, -scale, - (wx_min + 0.5*w_width) * scale + 0.5*cr_width, (wy_min + 0.5*w_height) * scale + 0.5*cr_height); /* Second, build the color map. If no color printing is desired, * transform the print color map into a black-and-white color map by * making the background color transparent and replacing all other * enabled colors with solid black. */ color_map = g_array_sized_new (FALSE, FALSE, sizeof(GedaColor), MAX_COLORS); color_map = g_array_append_vals (color_map, print_colors, MAX_COLORS); if (!is_color) { int i; for (i = 0; i < MAX_COLORS; i++) { GedaColor *c = &g_array_index (color_map, GedaColor, i); if (!c->enabled) continue; /* Disable background color & fully-transparent colors */ if (c->a == 0 || i == BACKGROUND_COLOR) { c->enabled = FALSE; continue; } /* Set any remaining colors solid black */ c->r = 0; c->g = 0; c->b = 0; c->a = ~0; } } /* Thirdly, create and initialise a renderer */ renderer = EDA_RENDERER (g_object_new (EDA_TYPE_RENDERER, "cairo-context", cr, "pango-context", pc, "color-map", color_map, "render-flags", is_raster ? EDA_RENDERER_FLAG_HINTING : 0, NULL)); /* Finally, actually do drawing */ cairo_save (cr); cairo_transform (cr, &mtx); /* Draw background */ eda_cairo_set_source_color (cr, BACKGROUND_COLOR, color_map); cairo_paint (cr); /* Draw all objects and cues */ for (iter = (GList *) s_page_objects (page); iter != NULL; iter = g_list_next (iter)) { eda_renderer_draw (renderer, (OBJECT *) iter->data); } for (iter = (GList *) s_page_objects (page); iter != NULL; iter = g_list_next (iter)) { eda_renderer_draw_cues (renderer, (OBJECT *) iter->data); } cairo_restore (cr); g_object_unref (renderer); g_array_free (color_map, TRUE); }