Beispiel #1
0
static gboolean
check_cairo (gboolean verbose)
{
#define CAIRO_MIN_MAJOR 1
#define CAIRO_MIN_MINOR 7
#define CAIRO_MIN_MICRO 1
#define CAIRO_MAX_MAJOR 1
#define CAIRO_MAX_MINOR 9
#define CAIRO_MAX_MICRO 0
    if (cairo_version () < CAIRO_VERSION_ENCODE (CAIRO_MIN_MAJOR, CAIRO_MIN_MINOR, CAIRO_MIN_MICRO)) {
        g_print ("ERROR: Cairo version %s cannot be used to run tests; must be at least %u.%u.%u.\n",
                 cairo_version_string (), CAIRO_MIN_MAJOR, CAIRO_MIN_MINOR, CAIRO_MIN_MICRO);
        return FALSE;
#ifdef CAIRO_MAX_MAJOR
    } else if (cairo_version () >= CAIRO_VERSION_ENCODE (CAIRO_MAX_MAJOR, CAIRO_MAX_MINOR, CAIRO_MAX_MICRO)) {
        g_print ("ERROR: Cairo version %s cannot be used to run tests; must be less than %u.%u.%u.\n",
                 cairo_version_string (), CAIRO_MAX_MAJOR, CAIRO_MAX_MINOR, CAIRO_MAX_MICRO);
        return FALSE;
#endif
    } else if (verbose) {
        g_print ("   OK: Cairo version %s is ok; must be at least %u.%u.%u.\n",
                 cairo_version_string (), CAIRO_MIN_MAJOR, CAIRO_MIN_MINOR, CAIRO_MIN_MICRO);
    }
    return TRUE;
}
Beispiel #2
0
static gchar *
sanity_check_cairo (void)
{
#define CAIRO_REQUIRED_MAJOR 1
#define CAIRO_REQUIRED_MINOR 12
#define CAIRO_REQUIRED_MICRO 2

  if (cairo_version () < CAIRO_VERSION_ENCODE (CAIRO_REQUIRED_MAJOR,
                                               CAIRO_REQUIRED_MINOR,
                                               CAIRO_REQUIRED_MICRO))
    {
      return g_strdup_printf
        ("The Cairo version being used is too old!\n\n"
         "GIMP requires Cairo version %d.%d.%d or later.\n"
         "Installed Cairo version is %s.\n\n"
         "Somehow you or your software packager managed\n"
         "to install GIMP with an older Cairo version.\n\n"
         "Please upgrade to Cairo version %d.%d.%d or later.",
         CAIRO_REQUIRED_MAJOR, CAIRO_REQUIRED_MINOR, CAIRO_REQUIRED_MICRO,
         cairo_version_string (),
         CAIRO_REQUIRED_MAJOR, CAIRO_REQUIRED_MINOR, CAIRO_REQUIRED_MICRO);
    }

#undef CAIRO_REQUIRED_MAJOR
#undef CAIRO_REQUIRED_MINOR
#undef CAIRO_REQUIRED_MICRO

  return NULL;
}
Beispiel #3
0
CAMLprim value
ml_CAIRO_VERSION_ENCODE (value maj, value min, value mic)
{
  return Val_int (CAIRO_VERSION_ENCODE (Int_val(maj), Int_val(min), Int_val(mic)));
}
Beispiel #4
0
static int gt_sketch_page_runner(GT_UNUSED int argc,
                                 const char **argv,
                                 int parsed_args,
                                 void *tool_arguments,
                                 GtError *err)
{
  SketchPageArguments *arguments = tool_arguments;
  int had_err = 0;
  GtFeatureIndex *features = NULL;
  GtRange qry_range, sequence_region_range;
  GtStyle *sty = NULL;
  GtStr *prog, *gt_style_file;
  GtDiagram *d = NULL;
  GtLayout *l = NULL;
  GtBioseq *bioseq = NULL;
  GtCanvas *canvas = NULL;
  const char *seqid = NULL, *outfile;
  unsigned long start, height, num_pages = 0;
  double offsetpos, usable_height;
  cairo_surface_t *surf = NULL;
  cairo_t *cr = NULL;
  GtTextWidthCalculator *twc;
  gt_error_check(err);

  features = gt_feature_index_memory_new();

  if (cairo_version() < CAIRO_VERSION_ENCODE(1, 8, 6))
    gt_warning("Your cairo library (version %s) is older than version 1.8.6! "
               "These versions contain a bug which may result in "
               "corrupted PDF output!", cairo_version_string());

  /* get style */
  sty = gt_style_new(err);
  if (gt_str_length(arguments->stylefile) == 0)
  {
    prog = gt_str_new();
    gt_str_append_cstr_nt(prog, argv[0],
                          gt_cstr_length_up_to_char(argv[0], ' '));
    gt_style_file = gt_get_gtdata_path(gt_str_get(prog), err);
    gt_str_delete(prog);
    gt_str_append_cstr(gt_style_file, "/sketch/default.style");
  }
  else
  {
    gt_style_file = gt_str_ref(arguments->stylefile);
  }
  had_err = gt_style_load_file(sty, gt_str_get(gt_style_file), err);

  outfile = argv[parsed_args];
  if (!had_err)
  {
    /* get features */
    had_err = gt_feature_index_add_gff3file(features, argv[parsed_args+1], err);
     if (!had_err && gt_str_length(arguments->seqid) == 0) {
      seqid = gt_feature_index_get_first_seqid(features);
      if (seqid == NULL)
      {
        gt_error_set(err, "GFF input file must contain a sequence region!");
        had_err = -1;
      }
    }
    else if (!had_err
               && !gt_feature_index_has_seqid(features,
                                              gt_str_get(arguments->seqid)))
    {
      gt_error_set(err, "sequence region '%s' does not exist in GFF input file",
                   gt_str_get(arguments->seqid));
      had_err = -1;
    }
    else if (!had_err)
      seqid = gt_str_get(arguments->seqid);
  }

  /* set text */
  if (gt_str_length(arguments->text) == 0)
  {
    gt_str_delete(arguments->text);
    arguments->text = gt_str_new_cstr(argv[parsed_args+1]);
  }

  if (!had_err)
  {
    /* set display range */
    gt_feature_index_get_range_for_seqid(features, &sequence_region_range,
                                         seqid);
    qry_range.start = (arguments->range.start == GT_UNDEF_ULONG ?
                         sequence_region_range.start :
                         arguments->range.start);
    qry_range.end   = (arguments->range.end == GT_UNDEF_ULONG ?
                         sequence_region_range.end :
                         arguments->range.end);

    /* set output format */
    if (strcmp(gt_str_get(arguments->format), "pdf") == 0)
    {
      surf = cairo_pdf_surface_create(outfile,
                                      mm_to_pt(arguments->pwidth),
                                      mm_to_pt(arguments->pheight));
    }
    else if (strcmp(gt_str_get(arguments->format), "ps") == 0)
    {
      surf =  cairo_ps_surface_create(outfile,
                                      mm_to_pt(arguments->pwidth),
                                      mm_to_pt(arguments->pheight));
    }
    gt_log_log("created page with %.2f:%.2f dimensions\n",
                                                  mm_to_pt(arguments->pwidth),
                                                  mm_to_pt(arguments->pheight));

    offsetpos = TEXT_SPACER + arguments->theight + TEXT_SPACER;
    usable_height = mm_to_pt(arguments->pheight)
                              - arguments->theight
                              - arguments->theight
                              - 4*TEXT_SPACER;

    if (gt_str_length(arguments->seqfile) > 0) {
      bioseq = gt_bioseq_new(gt_str_get(arguments->seqfile), err);
    }

    cr = cairo_create(surf);
    cairo_set_font_size(cr, 8);
    twc = gt_text_width_calculator_cairo_new(cr, sty);
    for (start = qry_range.start; start <= qry_range.end;
         start += arguments->width)
    {
      GtRange single_range;
      GtCustomTrack *ct = NULL;
      const char *seq;
      single_range.start = start;
      single_range.end = start + arguments->width;

      if (had_err)
        break;

      d = gt_diagram_new(features, seqid, &single_range, sty, err);
      if (!d) {
        had_err = -1;
        break;
      }
      if (bioseq) {
        seq = gt_bioseq_get_sequence(bioseq, 0);
        ct = gt_custom_track_gc_content_new(seq,
                                      gt_bioseq_get_sequence_length(bioseq, 0),
                                      800, 70, 0.4, true);
        gt_diagram_add_custom_track(d, ct);
      }

      l = gt_layout_new_with_twc(d, mm_to_pt(arguments->width), sty, twc, err);
      had_err = gt_layout_get_height(l, &height, err);
      if (!had_err) {
        if (gt_double_smaller_double(usable_height - 10 - 2*TEXT_SPACER
              - arguments->theight, offsetpos + height))
        {
            draw_header(cr, gt_str_get(arguments->text), argv[parsed_args+1],
                        seqid, num_pages, mm_to_pt(arguments->pwidth),
                        mm_to_pt(arguments->pheight),
                        arguments->theight);
          cairo_show_page(cr);
          offsetpos = TEXT_SPACER + arguments->theight + TEXT_SPACER;
          num_pages++;
        }
        canvas = gt_canvas_cairo_context_new(sty,
                                             cr,
                                             offsetpos,
                                             mm_to_pt(arguments->pwidth),
                                             height,
                                             NULL,
                                             err);
        if (!canvas)
          had_err = -1;
        offsetpos += height;
        if (!had_err)
          had_err = gt_layout_sketch(l, canvas, err);
      }
      gt_canvas_delete(canvas);
      gt_layout_delete(l);
      gt_diagram_delete(d);
      if (ct)
        gt_custom_track_delete(ct);
    }
    draw_header(cr, gt_str_get(arguments->text), argv[parsed_args+1], seqid,
                num_pages, mm_to_pt(arguments->pwidth),
                mm_to_pt(arguments->pheight),
                arguments->theight);
    cairo_show_page(cr);
    num_pages++;
    gt_log_log("finished, should be %lu pages\n", num_pages);
    gt_text_width_calculator_delete(twc);
    cairo_destroy(cr);
    cairo_surface_flush(surf);
    cairo_surface_finish(surf);
    cairo_surface_destroy(surf);
    cairo_debug_reset_static_data();
    if (bioseq)
      gt_bioseq_delete(bioseq);
    gt_style_delete(sty);
    gt_str_delete(gt_style_file);
    gt_feature_index_delete(features);
  }
  return had_err;
}
Beispiel #5
0
bool wxGTKCairoDCImpl::DoStretchBlit(int xdest, int ydest, int dstWidth, int dstHeight, wxDC* source, int xsrc, int ysrc, int srcWidth, int srcHeight, wxRasterOperationMode rop, bool useMask, int xsrcMask, int ysrcMask)
{
    wxCHECK_MSG(IsOk(), false, "invalid DC");
    wxCHECK_MSG(source && source->IsOk(), false, "invalid source DC");

    cairo_t* cr = NULL;
    if (m_graphicContext)
        cr = static_cast<cairo_t*>(m_graphicContext->GetNativeContext());
    cairo_t* cr_src = NULL;
    wxGraphicsContext* gc_src = source->GetGraphicsContext();
    if (gc_src)
        cr_src = static_cast<cairo_t*>(gc_src->GetNativeContext());

    if (cr == NULL || cr_src == NULL)
        return false;

    const int xsrc_dev = source->LogicalToDeviceX(xsrc);
    const int ysrc_dev = source->LogicalToDeviceY(ysrc);

    cairo_surface_t* surfaceSrc = cairo_get_target(cr_src);
    cairo_surface_flush(surfaceSrc);

    cairo_surface_t* surfaceTmp = NULL;
    // If destination (this) and source wxDC refer to the same Cairo context
    // it means that we operate on one surface and results of drawing
    // can be invalid if destination and source regions overlap.
    // In such situation we have to copy source surface to the temporary
    // surface and use this copy in the drawing operations.
    if ( cr == cr_src )
    {
        // Check if destination and source regions overlap.
        // If necessary, copy source surface to the temporary one.
        if (wxRect(xdest, ydest, dstWidth, dstHeight)
            .Intersects(wxRect(xsrc, ysrc, srcWidth, srcHeight)))
        {
            const int w = cairo_image_surface_get_width(surfaceSrc);
            const int h = cairo_image_surface_get_height(surfaceSrc);
#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 12, 0)
            if ( cairo_version() >= CAIRO_VERSION_ENCODE(1, 12, 0) )
            {
                surfaceTmp = cairo_surface_create_similar_image(surfaceSrc,
                     cairo_image_surface_get_format(surfaceSrc),
                     w, h);
            }
            else
#endif // Cairo 1.12
            {
                surfaceTmp = cairo_surface_create_similar(surfaceSrc,
                     CAIRO_CONTENT_COLOR_ALPHA,
                     w, h);
            }
            cairo_t* crTmp = cairo_create(surfaceTmp);
            cairo_set_source_surface(crTmp, surfaceSrc, 0, 0);
            cairo_rectangle(crTmp, 0.0, 0.0, w, h);
            cairo_set_operator(crTmp, CAIRO_OPERATOR_SOURCE);
            cairo_fill(crTmp);
            cairo_destroy(crTmp);
            cairo_surface_flush(surfaceTmp);
            surfaceSrc = surfaceTmp;
        }
    }
    cairo_save(cr);
    cairo_translate(cr, xdest, ydest);
    cairo_rectangle(cr, 0, 0, dstWidth, dstHeight);
    double sx, sy;
    source->GetUserScale(&sx, &sy);
    cairo_scale(cr, dstWidth / (sx * srcWidth), dstHeight / (sy * srcHeight));
    cairo_set_source_surface(cr, surfaceSrc, -xsrc_dev, -ysrc_dev);
    const wxRasterOperationMode rop_save = m_logicalFunction;
    SetLogicalFunction(rop);
    cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST);
    cairo_surface_t* maskSurf = NULL;
    if (useMask)
    {
        const wxBitmap& bitmap = source->GetImpl()->GetSelectedBitmap();
        if (bitmap.IsOk())
        {
            wxMask* mask = bitmap.GetMask();
            if (mask)
                maskSurf = *mask;
        }
    }
    if (maskSurf)
    {
        int xsrcMask_dev = xsrc_dev;
        int ysrcMask_dev = ysrc_dev;
        if (xsrcMask != -1)
            xsrcMask_dev = source->LogicalToDeviceX(xsrcMask);
        if (ysrcMask != -1)
            ysrcMask_dev = source->LogicalToDeviceY(ysrcMask);
        cairo_clip(cr);
        cairo_mask_surface(cr, maskSurf, -xsrcMask_dev, -ysrcMask_dev);
    }
    else
    {
        cairo_fill(cr);
    }
    cairo_restore(cr);
    if ( surfaceTmp )
    {
        cairo_surface_destroy(surfaceTmp);
    }
    m_logicalFunction = rop_save;
    return true;
}
Beispiel #6
0
static gboolean
path_test_convert_to_cairo_path (CallbackData *data)
{
    cairo_surface_t *surface;
    cairo_t *cr;
    cairo_path_t *cpath;
    guint i, j;
    ClutterKnot path_start = { 0, 0 }, last_point = { 0, 0 };

    /* Create a temporary image surface and context to hold the cairo
       path */
    surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 10, 10);
    cr = cairo_create (surface);

    /* Convert to a cairo path */
    clutter_path_to_cairo_path (data->path, cr);

    /* Get a copy of the cairo path data */
    cpath = cairo_copy_path (cr);

    /* Convert back to a clutter path */
    clutter_path_clear (data->path);
    clutter_path_add_cairo_path (data->path, cpath);

    /* The relative nodes will have been converted to absolute so we
       need to reflect this in the node array for comparison */
    for (i = 0; i < data->n_nodes; i++)
    {
        switch (data->nodes[i].type)
        {
        case CLUTTER_PATH_MOVE_TO:
            path_start = last_point = data->nodes[i].points[0];
            break;

        case CLUTTER_PATH_LINE_TO:
            last_point = data->nodes[i].points[0];
            break;

        case CLUTTER_PATH_CURVE_TO:
            last_point = data->nodes[i].points[2];
            break;

        case CLUTTER_PATH_REL_MOVE_TO:
            last_point.x += data->nodes[i].points[0].x;
            last_point.y += data->nodes[i].points[0].y;
            data->nodes[i].points[0] = last_point;
            data->nodes[i].type = CLUTTER_PATH_MOVE_TO;
            path_start = last_point;
            break;

        case CLUTTER_PATH_REL_LINE_TO:
            last_point.x += data->nodes[i].points[0].x;
            last_point.y += data->nodes[i].points[0].y;
            data->nodes[i].points[0] = last_point;
            data->nodes[i].type = CLUTTER_PATH_LINE_TO;
            break;

        case CLUTTER_PATH_REL_CURVE_TO:
            for (j = 0; j < 3; j++)
            {
                data->nodes[i].points[j].x += last_point.x;
                data->nodes[i].points[j].y += last_point.y;
            }
            last_point = data->nodes[i].points[2];
            data->nodes[i].type = CLUTTER_PATH_CURVE_TO;
            break;

        case CLUTTER_PATH_CLOSE:
            last_point = path_start;

            /* Cairo always adds a move to after every close so we need
               to insert one here. Since Cairo commit 166453c1abf2 it
               doesn't seem to do this anymore so will assume that if
               Cairo's minor version is >= 11 then it includes that
               commit */
            if (cairo_version () < CAIRO_VERSION_ENCODE (1, 11, 0))
            {
                memmove (data->nodes + i + 2, data->nodes + i + 1,
                         (data->n_nodes - i - 1) * sizeof (ClutterPathNode));
                data->nodes[i + 1].type = CLUTTER_PATH_MOVE_TO;
                data->nodes[i + 1].points[0] = last_point;
                data->n_nodes++;
            }
            break;
        }
    }

    /* Free the cairo resources */
    cairo_path_destroy (cpath);
    cairo_destroy (cr);
    cairo_surface_destroy (surface);

    return TRUE;
}