static void
ar_card_theme_kde_paint_card (ArCardTheme *card_theme,
                              cairo_t *cr,
                              int card_id)
{
  ArCardThemePreimage *preimage_card_theme = (ArCardThemePreimage *) card_theme;
  ArCardThemeKDE *theme = (ArCardThemeKDE *) card_theme;
  ArSvg *svg = preimage_card_theme->cards_svg;
  char node[32];
  cairo_rectangle_t *card_extents;
  cairo_matrix_t matrix;
  cairo_font_options_t *font_options;

  if (G_UNLIKELY (card_id == AR_CARD_SLOT)) {
    ar_svg_render_cairo (preimage_card_theme->slot_preimage,
                                 cr,
                                 preimage_card_theme->card_size.width,
                                 preimage_card_theme->card_size.height);
    return;
  }

  if (theme->legacy)
    ar_card_get_legacy_node_by_id_snprintf (node, sizeof (node), card_id);
  else
    ar_card_get_node_by_id_snprintf (node, sizeof (node), card_id);

  card_extents = ar_card_theme_kde_get_card_extents (theme, card_id, node);
  if (!card_extents)
    return;

  cairo_save (cr);

  font_options = ar_svg_get_font_options (svg);
  if (font_options) {
    cairo_set_antialias (cr, cairo_font_options_get_antialias (font_options));
    cairo_set_font_options (cr, font_options);
  }

  cairo_matrix_init_identity (&matrix);
  cairo_matrix_scale (&matrix,
                      preimage_card_theme->card_size.width / card_extents->width,
                      preimage_card_theme->card_size.height / card_extents->height);
  cairo_matrix_translate (&matrix, -card_extents->x, -card_extents->y);

  cairo_set_matrix (cr, &matrix);

  rsvg_handle_render_cairo_sub (RSVG_HANDLE (svg), cr, node);

  cairo_restore (cr);
}
Exemple #2
0
static int ui_set_antialias(lua_State *L)
{
	struct context *c = lua_touserdata(L, 1);
	int enable = lua_toboolean(L, 2);

	cairo_antialias_t antialias = (enable) ?
		CAIRO_ANTIALIAS_DEFAULT : CAIRO_ANTIALIAS_NONE;

	cairo_set_antialias(c->cr, antialias);

	cairo_font_options_t *options;
	options = cairo_font_options_create();
	cairo_font_options_set_antialias(options, antialias);
	cairo_set_font_options(c->cr, options);

	return 0;
}
Exemple #3
0
static cairo_test_status_t
draw (cairo_t *cr, int width, int height)
{
    cairo_font_options_t *font_options;
    cairo_scaled_font_t *scaled_font;
    FT_Face face;
    FT_ULong charcode;
    FT_UInt idx;
    int i = 0;
    cairo_glyph_t glyphs[NUM_GLYPHS];

    /* paint white so we don't need separate ref images for
     * RGB24 and ARGB32 */
    cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
    cairo_paint (cr);

    cairo_select_font_face (cr, "Bitstream Vera Sans",
			    CAIRO_FONT_SLANT_NORMAL,
			    CAIRO_FONT_WEIGHT_NORMAL);
    cairo_set_font_size (cr, TEXT_SIZE);

    font_options = cairo_font_options_create ();
    cairo_get_font_options (cr, font_options);
    cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_OFF);
    cairo_set_font_options (cr, font_options);
    cairo_font_options_destroy (font_options);

    cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);

    scaled_font = cairo_get_scaled_font (cr);
    face = cairo_ft_scaled_font_lock_face (scaled_font);
    {
	charcode = FT_Get_First_Char(face, &idx);
	while (idx && (i < NUM_GLYPHS)) {
	    glyphs[i] = (cairo_glyph_t) {idx, PAD + GRID_SIZE * (i/GRID_ROWS), PAD + TEXT_SIZE + GRID_SIZE * (i%GRID_ROWS)};
	    i++;
	    charcode = FT_Get_Next_Char(face, charcode, &idx);
	}
    }
    cairo_ft_scaled_font_unlock_face (scaled_font);

    cairo_show_glyphs(cr, glyphs, i);

    return CAIRO_TEST_SUCCESS;
}
Exemple #4
0
ScreenPainter::ScreenPainter(ScPainter *p, PageItem *item)
	: m_painter(p)
	, m_item(item)
	, m_fillColor("", -1)
	, m_strokeColor("", -1)
	, m_cairoFace(NULL)
	, m_faceIndex(-10) // ScFace::faceIndex() defaults to -1, we need a different value
{
	m_painter->save();

	// Use slight hinting to be closer to old Scribus behaviour
	// We can use CAIRO_HINT_STYLE_NONE to be even more closer, but
	// slight is a good compromise
	cairo_font_options_t* options = cairo_font_options_create();
	cairo_font_options_set_hint_style(options, CAIRO_HINT_STYLE_SLIGHT);
	cairo_set_font_options(m_painter->context(), options);
	cairo_font_options_destroy(options);
}
Exemple #5
0
int renderGlyphs2Cairo(imageObj *img, textPathObj *tp, colorObj *c, colorObj *oc, int ow) {
  cairo_renderer *r = CAIRO_RENDERER(img);
  cairoCacheData *cache = MS_IMAGE_RENDERER_CACHE(img);
  cairoFaceCache *cairo_face = NULL;
  FT_Face prevface = NULL;
  int g;

  cairo_set_font_size(r->cr,MS_NINT(tp->glyph_size * 96.0/72.0));
  for(g=0;g<tp->numglyphs;g++) {
    glyphObj *gl = &tp->glyphs[g];
    cairo_glyph_t glyph;
    /* load the glyph's face into cairo, if not already present */
    if(gl->face->face != prevface) {
      cairo_face = getCairoFontFace(cache,gl->face->face);
      cairo_set_font_face(r->cr, cairo_face->face);
      cairo_set_font_options(r->cr,cairo_face->options);
      prevface = gl->face->face;
      cairo_set_font_size(r->cr,MS_NINT(tp->glyph_size * 96.0/72.0));
    }
    cairo_save(r->cr);
    cairo_translate(r->cr,gl->pnt.x,gl->pnt.y);
    if(gl->rot != 0.0)
      cairo_rotate(r->cr, -gl->rot);
    glyph.x = glyph.y = 0;
    glyph.index = gl->glyph->key.codepoint;
    cairo_glyph_path(r->cr,&glyph,1);
    cairo_restore(r->cr);
  }
  if (oc) {
    cairo_save(r->cr);
    msCairoSetSourceColor(r->cr, oc);
    cairo_set_line_width(r->cr, ow + 1);
    cairo_stroke_preserve(r->cr);
    cairo_restore(r->cr);
  }
  if(c) {
    msCairoSetSourceColor(r->cr, c);
    cairo_fill(r->cr);
  }
  cairo_new_path(r->cr);
  return MS_SUCCESS;
}
Exemple #6
0
static double
count_glyphs (double font_size,
	      cairo_antialias_t antialias,
	      cairo_t *cr, int width, int height)
{
    const char text[] = "the jay, pig, fox, zebra and my wolves quack";
    cairo_scaled_font_t *scaled_font;
    cairo_glyph_t *glyphs = NULL;
    cairo_text_extents_t extents;
    cairo_font_options_t *options;
    cairo_status_t status;
    int num_glyphs;
    int glyphs_per_line, lines_per_loop;

    options = cairo_font_options_create ();
    cairo_font_options_set_antialias (options, antialias);
    cairo_set_font_options (cr, options);
    cairo_font_options_destroy (options);

    cairo_select_font_face (cr,
			    "@cairo:",
			    CAIRO_FONT_SLANT_NORMAL,
			    CAIRO_FONT_WEIGHT_NORMAL);
    cairo_set_font_size (cr, font_size);
    scaled_font = cairo_get_scaled_font (cr);
    status = cairo_scaled_font_text_to_glyphs (scaled_font, 0., 0.,
					       text, -1,
					       &glyphs, &num_glyphs,
					       NULL, NULL,
					       NULL);
    if (status)
	return 0;

    cairo_scaled_font_glyph_extents (scaled_font,
				     glyphs, num_glyphs,
				     &extents);
    cairo_glyph_free (glyphs);

    glyphs_per_line = num_glyphs * width / extents.width + 1;
    lines_per_loop = height / extents.height + 1;
    return glyphs_per_line * lines_per_loop / 1000.; /* kiloglyphs */
}
Exemple #7
0
static cairo_t *
_cairo_user_scaled_font_create_meta_context (cairo_user_scaled_font_t *scaled_font)
{
    cairo_content_t content;
    cairo_surface_t *meta_surface;
    cairo_t *cr;

    content = scaled_font->base.options.antialias == CAIRO_ANTIALIAS_SUBPIXEL ?
						     CAIRO_CONTENT_COLOR_ALPHA :
						     CAIRO_CONTENT_ALPHA;

    meta_surface = _cairo_meta_surface_create (content, -1, -1);
    cr = cairo_create (meta_surface);
    cairo_surface_destroy (meta_surface);

    cairo_set_matrix (cr, &scaled_font->base.scale);
    cairo_set_font_size (cr, 1.0);
    cairo_set_font_options (cr, &scaled_font->base.options);

    return cr;
}
Exemple #8
0
static cairo_test_status_t
draw (cairo_t *cr, int width, int height)
{
    cairo_text_extents_t extents;
    cairo_font_options_t *font_options;
    const char black[] = "black", blue[] = "blue";

    /* We draw in the default black, so paint white first. */
    cairo_save (cr);
    cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */
    cairo_paint (cr);
    cairo_restore (cr);

    cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY " Sans",
			    CAIRO_FONT_SLANT_NORMAL,
			    CAIRO_FONT_WEIGHT_NORMAL);
    cairo_set_font_size (cr, TEXT_SIZE);

    font_options = cairo_font_options_create ();
    cairo_get_font_options (cr, font_options);
    cairo_font_options_set_antialias (font_options, CAIRO_ANTIALIAS_GRAY);
    cairo_set_font_options (cr, font_options);

    cairo_font_options_destroy (font_options);

    cairo_set_source_rgb (cr, 0, 0, 0); /* black */
    cairo_text_extents (cr, black, &extents);
    cairo_move_to (cr, -extents.x_bearing, -extents.y_bearing);
    cairo_show_text (cr, black);
    cairo_translate (cr, 0, -extents.y_bearing + 1);

    cairo_set_source_rgb (cr, 0, 0, 1); /* blue */
    cairo_text_extents (cr, blue, &extents);
    cairo_move_to (cr, -extents.x_bearing, -extents.y_bearing);
    cairo_show_text (cr, blue);

    return CAIRO_TEST_SUCCESS;
}
Exemple #9
0
static cairo_test_status_t
draw (cairo_t *cr, int width, int height)
{
    cairo_font_options_t *options;

    cairo_set_source_rgb (cr, 1, 1, 1);
    cairo_paint (cr);
    cairo_set_source_rgb (cr, 0, 0, 0);

    cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);

    cairo_select_font_face (cr,
			    "@cairo:",
			    CAIRO_FONT_SLANT_NORMAL,
			    CAIRO_FONT_WEIGHT_NORMAL);

    options = cairo_font_options_create ();
    cairo_font_options_set_antialias (options, CAIRO_ANTIALIAS_NONE);
    cairo_set_font_options (cr, options);
    cairo_font_options_destroy (options);

    cairo_set_font_size (cr, 16);

    cairo_move_to (cr, 4, 14);
    cairo_show_text (cr, "Is cairo's twin giza?");

    cairo_move_to (cr, 4, 34);
    cairo_text_path (cr, "Is cairo's twin giza?");
    cairo_fill (cr);

    cairo_move_to (cr, 4, 54);
    cairo_text_path (cr, "Is cairo's twin giza?");
    cairo_set_line_width (cr, 2/16.);
    cairo_stroke (cr);

    return CAIRO_TEST_SUCCESS;
}
Exemple #10
0
static cairo_test_status_t
draw (cairo_t *cr, int width, int height)
{
    cairo_text_extents_t extents;
    cairo_font_options_t *font_options;
    static char black[] = "black", blue[] = "blue";

    cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
    cairo_paint (cr);

    cairo_select_font_face (cr, "Bitstream Vera Sans",
			    CAIRO_FONT_SLANT_NORMAL,
			    CAIRO_FONT_WEIGHT_NORMAL);
    cairo_set_font_size (cr, TEXT_SIZE);

    font_options = cairo_font_options_create ();
    cairo_get_font_options (cr, font_options);
    cairo_font_options_set_antialias (font_options, CAIRO_ANTIALIAS_SUBPIXEL);
    cairo_font_options_set_subpixel_order (font_options, CAIRO_SUBPIXEL_ORDER_RGB);
    cairo_set_font_options (cr, font_options);

    cairo_font_options_destroy (font_options);

    cairo_set_source_rgb (cr, 0, 0, 0); /* black */
    cairo_text_extents (cr, black, &extents);
    cairo_move_to (cr, -extents.x_bearing, -extents.y_bearing);
    cairo_show_text (cr, black);
    cairo_translate (cr, 0, -extents.y_bearing + 1);

    cairo_set_source_rgb (cr, 0, 0, 1); /* blue */
    cairo_text_extents (cr, blue, &extents);
    cairo_move_to (cr, -extents.x_bearing, -extents.y_bearing);
    cairo_show_text (cr, blue);

    return CAIRO_TEST_SUCCESS;
}
Exemple #11
0
void GUIFont_GetGreaterSize(const char *AFontName, float AHeight, unsigned int *ACharWidth, unsigned int *ACharHeight)
{
  cairo_text_extents_t *BExtents = (cairo_text_extents_t *)malloc(sizeof(cairo_text_extents_t));
  unsigned char *BText = (unsigned char *)malloc(sizeof(unsigned char) * 2);
  BText[0] = 0;
  BText[1] = '\0';
  
  cairo_surface_t *BSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
                                                         1,
                                                         1);
  cairo_t *BContext = cairo_create(BSurface);
  
  cairo_font_options_t *cfo = cairo_font_options_create();
  cairo_font_options_set_antialias(cfo, CAIRO_ANTIALIAS_SUBPIXEL);
  cairo_set_font_options(BContext, cfo);
  cairo_select_font_face(BContext, AFontName, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
  cairo_set_font_size(BContext, AHeight);
  
  for (BText[0] = 0; BText[0] < 255; BText[0]++)
  {
    cairo_text_extents(BContext, BText, BExtents);
    if (BExtents)
    {
      if (*ACharHeight < BExtents->height)
      {
        *ACharHeight = BExtents->height;
      };
      if (*ACharWidth < BExtents->width)
      {
        *ACharWidth = BExtents->width;
      };
    };
  };
  cairo_destroy(BContext);
  cairo_surface_destroy(BSurface);
};
void Initialize_Graphics(cairo_t *cr)
{
//	int Height,OldMaxX;
//	int t,t1; // t is unused
//	int t1;
	int x,dx;

	MaxX = WINDOW_WIDTH;
	MaxY = WINDOW_WIDTH;

	#ifdef GUI_INTERFACE
	cairo_scale(SF_rgb_context, 1, 1);
	#endif

	#ifdef GUI
	cairo_scale(cr, 1, 1);
	#else
	cairo_scale(cr, 1.0/SCALE_F, 1.0/SCALE_F);
	#endif

	cairo_set_antialias(cr, CAIRO_ANTIALIAS_BEST);
	cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE);
	cairo_set_line_join(cr, CAIRO_LINE_JOIN_MITER);

	cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);

	if(cairo_surface_get_type(cairo_get_target(cr)) == CAIRO_SURFACE_TYPE_XLIB)
	{
		// Supply a value VAL between 100.0 and 240.0 (as a double)
		cairo_set_line_width(cr, (435.0 * 1) / ((double) MaxY * 1));
	}
	else if(cairo_surface_get_type(cairo_get_target(cr)) == CAIRO_SURFACE_TYPE_IMAGE)
	{
		#ifdef __APPLE__
			cairo_set_line_width(cr, DEFAULT_LINE_WIDTH);
		#else
			cairo_set_line_width(cr, DEFAULT_LINE_WIDTH);
		#endif
	}
	else // Mostly quartz?
	{
		cairo_set_line_width(cr, (390.1 * 1) / ((double) MaxY * 1)); // for image_surf use 239
	}
//	cairo_set_line_width(cr, (90.1 * 1) / ((double) MaxY * 1));

////	 Cairo uses a different coordinate system than graphics.h, so we reflect Cairo's through
////	 the x-asis to make it equal to that of graphics.h.
////	cairo_matrix_t x_reflection_matrix;
	// Reflecting it however means that text will also be reflected. We therefore also use a
	// reflection matrix for drawing fonts to reflect text back.
//	cairo_matrix_t font_reflection_matrix;

	// We need the options to turn off font anti-aliasing
	cairo_font_options_t *font_options = cairo_font_options_create();
//	cairo_matrix_init_identity(&x_reflection_matrix);
//	x_reflection_matrix.yy = -1.0;
//	cairo_set_matrix(cr, &x_reflection_matrix);

	cairo_set_font_size(cr, POINTS_FONT_SIZE);
//	cairo_set_font_size(cr, 5.9);
//	cairo_get_font_matrix(cr, &font_reflection_matrix);
//	font_reflection_matrix.yy = font_reflection_matrix.yy * -1;
//	font_reflection_matrix.x0 += side_panel_size; // see (1)

//	cairo_set_font_matrix(cr, &font_reflection_matrix);
	// Translate negative height down because the reflection draws on top of the drawing surface
	// (i.e. out of frame, directly on top of the frame)

	// (1) Also translate the matrix over the x-axis to emulate the fact that DOS places the SF
	// square in the middle.
//	cairo_translate(cr, side_panel_size, -MaxY);
//	cairo_translate(cr, 0, -MaxY);

	// Turning off anti-alaising
	cairo_get_font_options(cr, font_options);
	cairo_font_options_set_antialias(font_options, CAIRO_ANTIALIAS_BEST);
	cairo_set_font_options(cr, font_options);
	cairo_select_font_face(cr,"DriodSans",CAIRO_FONT_SLANT_NORMAL,CAIRO_FONT_WEIGHT_NORMAL);
	cairo_font_options_destroy(font_options);


	// Sets all the values in the array to the empty path
	// Gives a vague warning, probably because this only works for types with the size of an int
	// (source: SO)
//	memset(PrevMissile, empty_path, MAX_NO_OF_MISSILES);
//	PrevMissile = {empty_path};
	// Attemps above don't work, so we initialize manually

	// clears the screen, probably the dos screen, and sets the current graphics write
	// pointer to (0,0)
	//	cleardevice();

	//	The "textheight" function returns the height of a string in pixels.
//	Height=textheight("H"); /* Get basic text height */
//	Height = TEXT_HEIGHT;
//
// 	OldMaxX=MaxX;
//  t1=4*Height;
//
//  Panel_Y_End=MaxY;
//  Panel_Y_Start=MaxY-t1+2;
//  MaxY_Panel=Panel_Y_End-Panel_Y_Start;
//  MaxY=MaxY-t1;
//	MaxX=MaxY;

	// Any modern graphics library should handle this "if" statements themselves, if needed at
	// all because we don't really need to know anymore wether or not we are on a vga display.
	// This aspect ratio stuff has to do with the fact if your display has square pixels or not.
	// AspectRatio is defined in opengraphics. Pixels are always square nowadays
//	if(AspectRatio==1.0) /* VGA HI */ square pixel ratio
//	MaxX=MaxY;
//	else	/* for all others */
//	{
//		MaxX=MaxX*AspectRatio;	/********* MaxX and MaxY give a square */
//		MaxX=MaxX-t1/AspectRatio;	/******** less two panel lines */
//	}
//	Xmargin=OldMaxX/2-MaxX/2;
//	printf("Xmargin: %d", Xmargin);
//	cairo_translate(cr, Xmargin, 0);
	// -- void setviewport(int left, int top, int right, int bottom, int clip);
	// setviewport function is used to restrict drawing to a particular portion on the screen. 	// For example "setviewport(100 , 100, 200, 200, 1)" will restrict our drawing activity
	// inside the rectangle(100,100, 200, 200).
	//
	// left, top, right, bottom are the coordinates of main diagonal of rectangle in which we wish to restrict our drawing. Also note that the point (left, top) becomes the new origin.
//	setviewport( Xmargin, 0, Xmargin+MaxX, MaxY, 1);

	dx=MaxX/8;
	Points_X=x=2*TEXT_WIDTH;
	x=x+dx; Control_X=x;
	x=x+dx; Velocity_X=x;
	x=x+dx; Vulner_X=x;
	x=x+dx; IFF_X=x;
	x=x+dx; Interval_X=x;
	x=x+dx; Speed_X=x;
	x=x+dx; Shots_X=x;
}
Exemple #13
0
static cairo_test_status_t
cairo_test_for_target (cairo_test_t			 *test,
		       cairo_boilerplate_target_t	 *target,
		       int				  dev_offset)
{
    cairo_test_status_t status;
    cairo_surface_t *surface = NULL;
    cairo_t *cr;
    char *png_name, *ref_name, *diff_name, *offset_str;
    cairo_test_status_t ret = CAIRO_TEST_SUCCESS;
    cairo_content_t expected_content;
    cairo_font_options_t *font_options;
    const char *format;

    /* Get the strings ready that we'll need. */
    format = cairo_boilerplate_content_name (target->content);
    if (dev_offset)
	xasprintf (&offset_str, "-%d", dev_offset);
    else
	offset_str = strdup("");

    xasprintf (&png_name, "%s-%s-%s%s%s",
	       test->name,
	       target->name,
	       format,
	       offset_str, CAIRO_TEST_PNG_SUFFIX);
    ref_name = cairo_ref_name_for_test_target_format (test->name, target->name, format);
    xasprintf (&diff_name, "%s-%s-%s%s%s",
	       test->name,
	       target->name,
	       format,
	       offset_str, CAIRO_TEST_DIFF_SUFFIX);

    if (target->is_vector) {
	int i;

	for (i = 0; vector_ignored_tests[i] != NULL; i++)
	    if (strcmp (test->name, vector_ignored_tests[i]) == 0) {
		cairo_test_log ("Error: Skipping for vector target %s\n", target->name);
		ret = CAIRO_TEST_UNTESTED;
		goto UNWIND_STRINGS;
	    }
    }

    if (ret == CAIRO_TEST_SUCCESS) {
	/* Run the actual drawing code. */

	if (test->width && test->height) {
	    test->width += dev_offset;
	    test->height += dev_offset;
	}

	surface = (target->create_surface) (test->name,
					    target->content,
					    test->width,
					    test->height,
					    CAIRO_BOILERPLATE_MODE_TEST,
					    &target->closure);

	if (test->width && test->height) {
	    test->width -= dev_offset;
	    test->height -= dev_offset;;
	}
    }

    if (surface == NULL) {
	cairo_test_log ("Error: Failed to set %s target\n", target->name);
	ret = CAIRO_TEST_UNTESTED;
	goto UNWIND_STRINGS;
    }

    /* Check that we created a surface of the expected type. */
    if (cairo_surface_get_type (surface) != target->expected_type) {
	cairo_test_log ("Error: Created surface is of type %d (expected %d)\n",
			cairo_surface_get_type (surface), target->expected_type);
	ret = CAIRO_TEST_FAILURE;
	goto UNWIND_SURFACE;
    }

    /* Check that we created a surface of the expected content,
     * (ignore the articifical
     * CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED value).
     */
    expected_content = target->content;
    if (expected_content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED)
	expected_content = CAIRO_CONTENT_COLOR_ALPHA;

    if (cairo_surface_get_content (surface) != expected_content) {
	cairo_test_log ("Error: Created surface has content %d (expected %d)\n",
			cairo_surface_get_content (surface), expected_content);
	ret = CAIRO_TEST_FAILURE;
	goto UNWIND_SURFACE;
    }

    cairo_surface_set_device_offset (surface, dev_offset, dev_offset);

    cr = cairo_create (surface);

    /* Clear to transparent (or black) depending on whether the target
     * surface supports alpha. */
    cairo_save (cr);
    cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
    cairo_paint (cr);
    cairo_restore (cr);

    /* Set all components of font_options to avoid backend differences
     * and reduce number of needed reference images. */
    font_options = cairo_font_options_create ();
    cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE);
    cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_ON);
    cairo_font_options_set_antialias (font_options, CAIRO_ANTIALIAS_GRAY);
    cairo_set_font_options (cr, font_options);
    cairo_font_options_destroy (font_options);

    status = (test->draw) (cr, test->width, test->height);

    /* Then, check all the different ways it could fail. */
    if (status) {
	cairo_test_log ("Error: Function under test failed\n");
	ret = status;
	goto UNWIND_CAIRO;
    }

    if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) {
	cairo_test_log ("Error: Function under test left cairo status in an error state: %s\n",
			cairo_status_to_string (cairo_status (cr)));
	ret = CAIRO_TEST_FAILURE;
	goto UNWIND_CAIRO;
    }

    /* Skip image check for tests with no image (width,height == 0,0) */
    if (test->width != 0 && test->height != 0) {
	buffer_diff_result_t result;
	cairo_status_t diff_status;
	xunlink (png_name);
	(target->write_to_png) (surface, png_name);

	if (!ref_name) {
	    cairo_test_log ("Error: Cannot find reference image for %s/%s-%s-%s%s\n",srcdir,
			    test->name,
			    target->name,
			    format,
			    CAIRO_TEST_REF_SUFFIX);
	    ret = CAIRO_TEST_FAILURE;
	    goto UNWIND_CAIRO;
	}

	cairo_test_log ("Comparing result against reference image: %s\n", ref_name);

	if (target->content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED) {
	    diff_status= image_diff_flattened (png_name, ref_name, diff_name,
					       dev_offset, dev_offset, 0, 0, &result);
	} else {
	    diff_status = image_diff (png_name, ref_name, diff_name,
				      dev_offset, dev_offset, 0, 0, &result);
	}
	if (diff_status) {
	    cairo_test_log ("Error: Failed to compare images: %s\n",
			    cairo_status_to_string (diff_status));
	    ret = CAIRO_TEST_FAILURE;
	    goto UNWIND_CAIRO;
	}
	if (result.pixels_changed && result.max_diff > target->error_tolerance) {
	    ret = CAIRO_TEST_FAILURE;
	    goto UNWIND_CAIRO;
	}
    }

UNWIND_CAIRO:
    cairo_destroy (cr);
UNWIND_SURFACE:
    cairo_surface_destroy (surface);

    cairo_debug_reset_static_data ();

    if (target->cleanup)
	target->cleanup (target->closure);

UNWIND_STRINGS:
    if (png_name)
      free (png_name);
    if (ref_name)
      free (ref_name);
    if (diff_name)
      free (diff_name);
    if (offset_str)
      free (offset_str);

    return ret;
}
Exemple #14
0
/**
 * Initialize a new console
 */
Console* new_Console(cairo_t* context, double font_size)
{
  //printf("Console::Console(cairo_t@%p)\n", context);

  Console* self;
  self = malloc(sizeof(Console));
  self->head = null;
  self->tail = null;
  self->cursor = null;
  self->width = default_width;
  self->height = default_height;
  self->pad = 4;
  self->font_filename = "./Monaco_Linux.ttf"; /* TODO */
  self->font_size = font_size;
  self->transparency = 1.0;
  self->antialias_text = false;
  self->antialias_graphics = true;
  
  /* initialize lithp, cairo - and define callbacks */
  self->lithp = new_LithpInterpreter();
  char* cairo_init [] = {
    //"(set 'libcairo             (xl:dlopen \"libcairo.dylib\"))",
    //"(set 'libcairo             (xl:dlopen \"libcairo.so.2\"))",
    //"(set 'libcairo (xl:dlopen \"/Users/antoine/Projects/phlo/install/lib/libcairo.dylib\"))",
#if defined(__linux__)
    "(set 'libcairo             (xl:dlopen \"libcairo.so.2\"))",
#elif defined(__APPLE__) && defined(__MACH__)
    "(set 'libcairo             (xl:dlopen \"libcairo.dylib\"))",
#endif
    "(set 'cairo:set-source-rgb       (xl:dlsym libcairo \"cairo_set_source_rgb\"))",
    "(set 'cairo:rectangle            (xl:dlsym libcairo \"cairo_rectangle\"))",
    "(set 'cairo:fill                 (xl:dlsym libcairo \"cairo_fill\"))",
    "(set 'cairo:translate            (xl:dlsym libcairo \"cairo_translate\"))",
    "(set 'cairo:rotate               (xl:dlsym libcairo \"cairo_rotate\"))",
    "(set 'cairo:move-to              (xl:dlsym libcairo \"cairo_move_to\"))",
    "(set 'cairo:set-source-rgba      (xl:dlsym libcairo \"cairo_set_source_rgba\"))",
    "(set 'console:width 492)",
    "(set 'console:height 344)",
    "(set 'pi 3.141592)",

    "(set 'pretty '(lambda (cr arc theta)                      "
    "  (cond ((lte arc 0.0) 0.0)                               "
    "        ('t (progn                                        "
    "              (cairo:rotate cr theta)                     "
    "              (cairo:rectangle cr 20.0 20.0 140.0 20.0)    "
    "              (cairo:fill cr)                             "
    "              (pretty cr (sub arc theta) theta))))))      ",

    "(set 'console:expose-event '(lambda (context)             "
    "  (cairo:set-source-rgb  context 0.5 0.5 1.0)         "
    "  (cairo:translate context (div console:width 2.0) (div console:height 2.0))"
    "  (pretty context (mul pi 2.0) (div pi 4.0))))",
    //"(set 'console:expose-event '(lambda (context) ()))",
    null
  };
  for (size_t t = 0; cairo_init[t] != null; t++) {
    Expression* callback = Expression_parse_utf8(cairo_init[t], null, &self->lithp->symbol_list); 
    _gc_protect(callback);
    Expression_eval(callback, self->lithp->environment);
    _gc_unprotect(callback);
  }


  /* initialize and configure console font */
  FT_Library  library;
  int error = FT_Init_FreeType(&library);
  if (error) { perror("Could not open FreeType library"); exit(EXIT_FAILURE); }
  self->font_face = malloc(sizeof(FT_Face*));
  error = FT_New_Face(library, self->font_filename, 0, self->font_face);
  if (error) { perror("Could not open font"); exit(EXIT_FAILURE); }
  cairo_set_font_face(context, cairo_ft_font_face_create_for_ft_face(*self->font_face, 0));
  cairo_set_font_size(context, self->font_size);
  cairo_font_options_t* font_options = cairo_font_options_create();
  cairo_get_font_options(context, font_options);
  if (self->antialias_text) {
    cairo_font_options_set_antialias(font_options, CAIRO_ANTIALIAS_NONE);
  }
  cairo_set_font_options(context, font_options);
  self->font_extents = malloc(sizeof(cairo_font_extents_t));
  cairo_font_extents(context, self->font_extents);

  /* some sample text */
  //wchar_t* test_text = L"ABCDEFGHIJKLM\nNOPQRSTUVWXYZ\nabcdefghijklm\nnopqrstuvwxyz\n1234567890\0";
  wchar_t* test_text = L"  \n  ";
  unsigned int n;
  for (n = 0; n < wcslen(test_text); n++) {
    //  Console_append(self, test_text[n]);
    Console_insert(self, test_text[n]);
  }
  self->cursor = self->head;

  return self;
}
Exemple #15
0
void Context::setFontOptions( const FontOptions *options )
{
	cairo_set_font_options( mCairo, const_cast<FontOptions*>( options )->getCairoFontOptions() );
}
Exemple #16
0
static GpStatus
MeasureString (GpGraphics *graphics, GDIPCONST WCHAR *stringUnicode, int *length, GDIPCONST GpFont *font, 
	GDIPCONST RectF *rc_org, GDIPCONST GpStringFormat *format, GpBrush *brush, RectF *boundingBox, 
	int *codepointsFitted, int *linesFilled, 
	WCHAR *CleanString, GpStringDetailStruct* StringDetails, GpDrawTextData *data)
{
	BYTE			*String;		/* Holds the UTF8 version of our sanitized string */
	unsigned long		StringLen;		/* Length of CleanString */
	GDIPCONST WCHAR		*Src;
	WCHAR	 		*Dest;
	unsigned long		i;
	unsigned long		j;
	GpStringDetailStruct	*CurrentDetail;
	GpStringDetailStruct	*CurrentLineStart;	/* For rendering engine, to bump LineLen */
	float			*TabStops;
	int			NumOfTabStops;
	int			WrapPoint;		/* Array index of wrap character */
	int			WrapX;			/* Width of text at wrap character */
	float			CursorX;		/* Current X position of drawing cursor */
	float			CursorY;		/* Current Y position of drawing cursor */
	int			MaxX;			/* Largest X of cursor */
	int			MaxXatY;		/* Y coordinate of line with largest X, needed for MaxX resetting on wrap */
	int			MaxY;			/* Largest Y of cursor */
	int			FrameWidth;		/* rc->Width (or rc->Height if vertical) */
	int			FrameHeight;		/* rc->Height (or rc->Width if vertical) */
	int			AlignHorz;		/* Horizontal Alignment mode */
	int			AlignVert;		/* Vertical Alignment mode */
	int			LineHeight;		/* Height of a line with given font */
	cairo_font_extents_t	FontExtent;		/* Info about our font */
	cairo_font_options_t	*FontOptions;
	RectF 			rc_coords, *rc = &rc_coords;
	float			FontSize;

	if (OPTIMIZE_CONVERSION (graphics)) {
		rc->X = rc_org->X;
		rc->Y = rc_org->Y;
		rc->Width = rc_org->Width;
		rc->Height = rc_org->Height;
	} else {
		rc->X = gdip_unitx_convgr (graphics, rc_org->X);
		rc->Y = gdip_unity_convgr (graphics, rc_org->Y);
		rc->Width = gdip_unitx_convgr (graphics, rc_org->Width);
		rc->Height = gdip_unity_convgr (graphics, rc_org->Height);
	}

#ifdef DRAWSTRING_DEBUG
	printf("GdipDrawString(...) called (length=%d, fontsize=%d)\n", length, (int)font->sizeInPixels);
#endif

	TabStops = format->tabStops;
	NumOfTabStops = format->numtabStops;

	/* Prepare our various buffers and variables */
	StringLen = *length;
	if (data)
		data->has_hotkeys = FALSE;

	/*
	  Set aliasing mode
	*/
	FontOptions = cairo_font_options_create();
	
	switch(graphics->text_mode) {
		default:
		case TextRenderingHintSystemDefault: {
			cairo_font_options_set_antialias(FontOptions, CAIRO_ANTIALIAS_DEFAULT);
			//cairo_font_options_set_hint_style(FontOptions, CAIRO_HINT_STYLE_NONE);
			//cairo_font_options_set_subpixel_order(FontOptions, CAIRO_SUBPIXEL_ORDER_DEFAULT);
			//cairo_font_options_set_hint_style(FontOptions, CAIRO_HINT_STYLE_DEFAULT);
			//cairo_font_options_set_hint_metrics(FontOptions, CAIRO_HINT_METRICS_DEFAULT);
			break;
		}

		// FIXME - pick matching settings for each text mode
		case TextRenderingHintSingleBitPerPixelGridFit:
		case TextRenderingHintSingleBitPerPixel:
		case TextRenderingHintAntiAliasGridFit:
		case TextRenderingHintAntiAlias: {
			cairo_font_options_set_antialias(FontOptions, CAIRO_ANTIALIAS_DEFAULT);
			break;
		}

		case TextRenderingHintClearTypeGridFit: {
			cairo_font_options_set_antialias(FontOptions, CAIRO_ANTIALIAS_DEFAULT);
			break;
		}
	}

	cairo_set_font_options(graphics->ct, FontOptions);
	cairo_font_options_destroy(FontOptions);

	// Do we want this here?

/* Commented out until we properly save/restore AA settings; should fix bug #76135
	cairo_set_antialias(graphics->ct, CAIRO_ANTIALIAS_NONE);
*/

	/*
	   Get font size information; how expensive is the cairo stuff here? 
	*/	
	cairo_set_font_face (graphics->ct, (cairo_font_face_t*) font->cairofnt);	/* Set our font; this will also be used for later drawing */

	/* this will always return the same value, except when printing */
	FontSize = (graphics->type == gtPostScript) ? font->emSize : font->sizeInPixels;
	cairo_set_font_size (graphics->ct, FontSize);
	
	cairo_font_extents (graphics->ct, &FontExtent);		/* Get the size we're looking for */
/*	cairo_font_set_transform(font->cairofnt, SavedMatrix);*/	/* Restore the matrix */

	if ((LineHeight=FontExtent.ascent)<1) {
		LineHeight=1;
	}

#ifdef DRAWSTRING_DEBUG
	printf("Font extents: ascent:%d, descent: %d, height:%d, maxXadvance:%d, maxYadvance:%d\n", (int)FontExtent.ascent, (int)FontExtent.descent, (int)FontExtent.height, (int)FontExtent.max_x_advance, (int)FontExtent.max_y_advance);
#endif

	/* Sanitize string, remove formatting chars and build description array */
#ifdef DRAWSTRING_DEBUG
	printf("GdipDrawString(...) Sanitizing string, StringLen=%d\n", StringLen);
#endif

	Src=stringUnicode;

	/* unless specified we don't consider the trailing spaces, unless there is just one space (#80680) */
	if ((format->formatFlags & StringFormatFlagsMeasureTrailingSpaces) == 0) {
		while ((StringLen > 0) && (isspace ((int) ( *(Src + StringLen - 1)))))
			StringLen--;
		if (StringLen == 0)
			StringLen = 1;
	}

	Dest=CleanString;
	CurrentDetail=StringDetails;
	for (i=0; i<StringLen; i++) {
		switch(*Src) {
			case '\r': { /* CR */
				Src++;
				continue;
			}

			case '\t': { /* Tab */
				if (NumOfTabStops > 0) {
					CurrentDetail->Flags |= STRING_DETAIL_TAB;
				}
				Src++;
				continue;
			}

			case '\n': { /* LF */
				CurrentDetail->Flags |= STRING_DETAIL_LF;
				CurrentDetail->Linefeeds++;
				Src++;
				continue;
			}

			case '&': {
				/* We print *all* chars if no hotkeys */
				if (format->hotkeyPrefix==HotkeyPrefixNone) {
					break;
				}

				Src++;
				if (*Src=='&') {
					/* We skipped the first '&', the break will 
					   make us drop to copying the second */
					break;
				}
				CurrentDetail->Flags |= STRING_DETAIL_HOTKEY;
				if (data)
					data->has_hotkeys = TRUE;
				continue;
			}

			/* Boy, this must be slow, FIXME somehow */
			default: {
				if (((format->formatFlags & StringFormatFlagsNoWrap)==0) || ((format->trimming != StringTrimmingCharacter) && (format->trimming != StringTrimmingNone))) {
					break;
				}
				/* Fall through */
			}

			case ' ':
			case '.':
			{
				/* Mark where we can break for a new line */
				CurrentDetail->Flags |= STRING_DETAIL_BREAK;
				break;
			}

		}
		*Dest=*Src;
		Src++;
		Dest++;
		CurrentDetail++;
	}
	*Dest='\0';	
	
	/* Recalculate StringLen; we may have shortened String */
	Dest=CleanString;
	StringLen=0;
	while (*Dest!=0) {
		StringLen++;
		Dest++;
	}

	/* Don't bother doing anything else if the length is 0 */
	if (StringLen == 0) {
		*length = 0;
		return Ok;
	}
	
	/* Convert string from Gdiplus format to UTF8, suitable for cairo */
	String = (BYTE*) ucs2_to_utf8 ((const gunichar2 *)CleanString, -1);
	if (!String)
		return OutOfMemory;

#ifdef DRAWSTRING_DEBUG
	printf("Sanitized string: >%s<, length %d (utf8-length:%d)\n", String, StringLen, strlen((char *)String));
#endif

	/* Generate size array */
	if (CalculateStringWidths (graphics->ct, font, CleanString, StringLen, StringDetails)==0) {
		/* FIXME; pick right return code */
		GdipFree(String);
		return Ok;
	}
	GdipFree (String);

	CursorX=0;
	CursorY=0;
	MaxX=0;
	MaxXatY=0;
	MaxY=0;
	CurrentLineStart=StringDetails;
	CurrentDetail=StringDetails;
	CurrentDetail->Flags |= STRING_DETAIL_LINESTART;
	WrapPoint=-1;
	WrapX=0;

	if (format->formatFlags & StringFormatFlagsDirectionVertical) {
		FrameWidth = SAFE_FLOAT_TO_UINT32 (rc->Height);
		FrameHeight = SAFE_FLOAT_TO_UINT32 (rc->Width);
	} else {
		FrameWidth = SAFE_FLOAT_TO_UINT32 (rc->Width);
		FrameHeight = SAFE_FLOAT_TO_UINT32 (rc->Height);
	}

#ifdef DRAWSTRING_DEBUG
	printf("Frame %d x %d\n", FrameWidth, FrameHeight);
#endif
	for (i=0; i<StringLen; i++) {
		/* Handle tabs and new lines */
		if (CurrentDetail->Flags & STRING_DETAIL_TAB) {
			float	tab_pos;
			int	tab_index;

			tab_pos = format->firstTabOffset;
			tab_index = 0;
			while (CursorX > tab_pos) {
				tab_pos += TabStops[tab_index % NumOfTabStops];
				tab_index++;
			}
			CursorX = tab_pos;
			CurrentLineStart = CurrentDetail;
			CurrentDetail->Flags |= STRING_DETAIL_LINESTART;
		}
		if (CurrentDetail->Flags & STRING_DETAIL_LF) {
			CursorX = 0;
			CursorY += LineHeight * CurrentDetail->Linefeeds;
			CurrentDetail->Flags |= STRING_DETAIL_LINESTART;
			CurrentLineStart = CurrentDetail;
#ifdef DRAWSTRING_DEBUG
			{
				int j;

				for (j=0; j<CurrentDetail->Linefeeds; j++) {
					printf("<LF>\n");
				}
			}
#endif
		}

#ifdef DRAWSTRING_DEBUG
		printf("[%3d] X: %3d, Y:%3d, '%c'  | ", i, (int)CursorX, (int)CursorY, CleanString[i]>=32 ? CleanString[i] : '?');
#endif
		/* Remember where to wrap next, but only if wrapping allowed */
		if (((format->formatFlags & StringFormatFlagsNoWrap)==0) && (CurrentDetail->Flags & STRING_DETAIL_BREAK)) {
			if (CleanString[i] == ' ') {
				WrapPoint=i+1;	/* We skip the break char itself, keeping it at the end of the old line */
			} else {
				WrapPoint=i;
			}

			if (CursorX>MaxX) {
				WrapX=CursorX;
			} else {
				WrapX=MaxX;
			}
#ifdef DRAWSTRING_DEBUG
			printf("<W>");
#endif
		}

		/* New line voids any previous wrap point */
		if (CurrentDetail->Flags & STRING_DETAIL_LINESTART) {
			WrapPoint=-1;
		}

		CurrentDetail->PosX=CursorX;
		CurrentDetail->PosY=CursorY;

		/* Advance cursor */
		CursorX+=CurrentDetail->Width;
		if (MaxX<CursorX) {
			MaxX=CursorX;
			MaxXatY=CursorY;
		}

		/* Time for a new line? Go back to last WrapPoint and wrap */
		if (FrameWidth && CursorX>FrameWidth) {
			if (WrapPoint!=-1) {
				/** Re-Calculate line lengths **/
				/* Old line */
				CurrentLineStart->LineLen-=i-WrapPoint;
				if (MaxXatY==CursorY) {
					MaxX=WrapX;
				}

				/* Remove the trailing space from being counted if we're not supposed to */
				if (((format->formatFlags & StringFormatFlagsMeasureTrailingSpaces)==0) && (WrapPoint>0)) {
					if (CleanString[WrapPoint-1]==' ') {
						if (MaxXatY==CursorY) {
							MaxX-=StringDetails[WrapPoint-1].Width;
						}
						StringDetails[WrapPoint-1].Width=0;
						CurrentLineStart->LineLen--;
					}
				}

				/* New line */
				CurrentLineStart=&(StringDetails[WrapPoint]);
				CurrentLineStart->Flags|=STRING_DETAIL_LINESTART;
				CurrentLineStart->LineLen=0;

				/* Generate CursorX/Y for new line */
				CursorY+=LineHeight;
				CursorX=CurrentLineStart->Width;

				i=WrapPoint;
#ifdef DRAWSTRING_DEBUG
				printf("\n<Forcing break at index %d, CursorX:%f, LineLen:%d>\n", WrapPoint, CursorX, CurrentLineStart->LineLen);
#endif
				CurrentDetail=&(StringDetails[WrapPoint]);
				CurrentDetail->PosX=0;
				CurrentDetail->PosY=CursorY;
				WrapPoint=-1;
			} else {
				/*
				   This line is too long and has no wrap points, check if we need to insert ellipsis.
				   To keep at least a bit of performance, we cheat - we don't actually calculate the
				   size of the elipsis chars but assume that they're always smaller than any other
				   character. And we don't try to hard to fit as many chars as possible.
				*/

				int	EndOfLine;

#ifdef DRAWSTRING_DEBUG
				printf("No wrappoint (yet) set\n");
#endif
				/* Find end of line, index i is the first char no longer visible on the line */
				EndOfLine=i;
				if ((format->formatFlags & StringFormatFlagsNoWrap)==0) {
					while (EndOfLine<StringLen && ((StringDetails[EndOfLine].Flags & STRING_DETAIL_LF)==0)) {
						EndOfLine++;
					}
				} else {
					while (EndOfLine<StringLen && ((StringDetails[EndOfLine].Flags & (STRING_DETAIL_LF | STRING_DETAIL_BREAK))==0)) {
						EndOfLine++;
					}
					if (EndOfLine<StringLen) {
						if (StringDetails[EndOfLine].Flags & STRING_DETAIL_BREAK) {
							EndOfLine++;
						}
					}
				}

				if ((format->trimming==StringTrimmingEllipsisWord) || (format->trimming==StringTrimmingEllipsisCharacter)) {
					if (CurrentLineStart->LineLen>3) {
						if (format->trimming==StringTrimmingEllipsisCharacter) {
							CleanString[i-1]='.';
							CleanString[i-2]='.';
							CleanString[i-3]='.';
						} else {
							int	found=0;

							j=i;
							while(j>(i-CurrentLineStart->LineLen)) {
								if (CleanString[j]==' ') {
									CleanString[j]='.';
									CurrentLineStart->LineLen-=i-j-1;

									if ((j+1)<EndOfLine) {
										CleanString[j+1]='.';
										CurrentLineStart->LineLen++;
									}

									if ((j+2)<EndOfLine) {
										CleanString[j+2]='.';
										CurrentLineStart->LineLen++;
									}
									found=1;
									break;
								}
								j--;
							}

							if (!found) {
								CleanString[i-1]='.';
								CleanString[i-2]='.';
								CleanString[i-3]='.';
							}
						}
					}
				} else if (format->trimming==StringTrimmingEllipsisPath) {
					int	k;
					float	LineWidth;

					/* Find end of line, index i is the first char no longer visible on the line */
					EndOfLine=i;
					while (EndOfLine<StringLen && ((StringDetails[EndOfLine].Flags & (STRING_DETAIL_LF | STRING_DETAIL_BREAK))==0)) {
						EndOfLine++;
					}

					/* Whack the center, make sure we've got space in the string */
					if (CurrentLineStart->LineLen>3) {
						j=i-(CurrentLineStart->LineLen/2);
						CleanString[j-1]='.';
						CleanString[j]='.';
						CleanString[j+1]='.';

						/* Have just enough to include our ellipsis */
						LineWidth=0;
						for (k=i-CurrentLineStart->LineLen; k<(j+1); k++) {
							LineWidth+=StringDetails[k].Width;
						}
						CurrentLineStart->LineLen=i-j+3;	/* 3=ellipsis */

						/* Now figure out how many chars from the end of the string we have to copy */
						j+=2;	/* Points to the char behind the last ellipsis */
						k=EndOfLine-1;
						while ((LineWidth+StringDetails[k].Width)<FrameWidth) {
							LineWidth+=StringDetails[k].Width;
							k--;
						}
						memcpy (&CleanString[j], &CleanString[k+1], sizeof(WCHAR)*(EndOfLine-k-1));

						CurrentLineStart->LineLen+=EndOfLine-k-1;
					} 
					
				} else {
#ifdef DRAWSTRING_DEBUG
					/* Just cut off the text */
					printf("End of line at index:%d\n", EndOfLine);
#endif
					CurrentLineStart->LineLen=EndOfLine;
				}

				if ((format->formatFlags & StringFormatFlagsNoWrap)!=0) {
					// Avoid endless loops, always print at least one char
					if (CurrentLineStart->LineLen == 0) {
						CurrentLineStart->LineLen = 1;
					}
					break;
				}

				/* avoid endless loop when wrapping is allowed */
				if (CurrentLineStart->LineLen == 0) {
					CurrentLineStart->LineLen = 1;
				}

				/* New line */
				CurrentLineStart=&(StringDetails[EndOfLine]);
				CurrentLineStart->Flags|=STRING_DETAIL_LINESTART;
				CurrentLineStart->LineLen=0;

				/* Generate CursorX/Y for new line */
				CursorY+=LineHeight;
				CursorX=CurrentLineStart->Width;

				i=EndOfLine;

				CurrentDetail=&(StringDetails[EndOfLine]);
				CurrentDetail->PosX=0;
				CurrentDetail->PosY=CursorY;
			}
		}


		/* Still visible? */
		if ((FrameWidth && CursorX>FrameWidth) || (FrameHeight && ((CursorY>FrameHeight) || ((format->formatFlags & StringFormatFlagsLineLimit) && (CursorY+LineHeight)>FrameHeight)))) {
			CurrentDetail->Flags|=STRING_DETAIL_HIDDEN;
#ifdef DRAWSTRING_DEBUG
			if (CurrentDetail->Flags & STRING_DETAIL_LINESTART) {
				printf("<LSTART-H>");
			} else {
				printf("<H>");
			}
#endif
		} else {
			if (MaxY<CursorY) {
				MaxY=CursorY;
			}
		}

#ifdef DRAWSTRING_DEBUG
		if (i % 3 == 2) {
			printf("\n");
		}
#endif

		CurrentDetail++;

		CurrentLineStart->LineLen++;
	}

	/* We ignored it above, for shorter of calculations, also, add a bit of padding */
	MaxY+=LineHeight+FontExtent.descent;

#ifdef DRAWSTRING_DEBUG
	printf("\n");

	printf("Bounding box: %d x %d\n", MaxX, MaxY);

	printf("Line layout [Total len %d]:\n", StringLen);
	for (i=0; i<StringLen; i++) {
		if (StringDetails[i].Flags & STRING_DETAIL_LF) {
			for (j=0; j<StringDetails[i].Linefeeds; j++) {
				printf("\n");
			}
		}
		if (StringDetails[i].Flags & STRING_DETAIL_LINESTART) {
			printf("[Len %2d %dx%d] ", StringDetails[i].LineLen, (int)StringDetails[i].PosX, (int)StringDetails[i].PosY);
			for (j=0; j<StringDetails[i].LineLen; j++) {
				printf("%c", CleanString[i+j]);
			}
			if (j == 0) {
				break;
			}
			i+=j-1;
			printf("\n");
		}
	}
#endif

	/* Prepare alignment handling */
	AlignHorz = format->alignment;
	if (format->formatFlags & StringFormatFlagsDirectionRightToLeft) {
		if (format->alignment==StringAlignmentNear) {
			AlignHorz=StringAlignmentFar;
		} else if (format->alignment==StringAlignmentFar) {
			AlignHorz=StringAlignmentNear;
		}
	}
	AlignVert = format->lineAlignment;

	/*
	   At this point we know our bounding box, what characters
	   are to be displayed and where every character goes
	*/
	if (boundingBox) {
		boundingBox->X = rc->X;
		boundingBox->Y = rc->Y;
		if (format->formatFlags & StringFormatFlagsDirectionVertical) {
			boundingBox->Width = MaxY;
			boundingBox->Height = MaxX;
		} else {
			boundingBox->Width = MaxX;
			boundingBox->Height = MaxY;
		}
		if ((rc->Width > 0) && (boundingBox->Width > rc->Width)) {
			boundingBox->Width = rc->Width;
		}
		if ((rc->Height > 0) && (boundingBox->Height > rc->Height)) {
			boundingBox->Height = rc->Height;
		}

		/* avoid conversion computations if possible */
		if (!OPTIMIZE_CONVERSION (graphics)) {
			boundingBox->X = gdip_convgr_unitx (graphics, boundingBox->X);
			boundingBox->Y = gdip_convgr_unity (graphics, boundingBox->Y);
			boundingBox->Width = gdip_convgr_unitx (graphics, boundingBox->Width);
			boundingBox->Height = gdip_convgr_unity (graphics, boundingBox->Height);
		}

		switch (AlignVert) {
		case StringAlignmentCenter:
			if (format->formatFlags & StringFormatFlagsDirectionVertical) {
				boundingBox->X += (FrameHeight - MaxY) * 0.5;
			} else {
				boundingBox->Y += (FrameHeight - MaxY) * 0.5;
			}
			break;
		case StringAlignmentFar:
			if (format->formatFlags & StringFormatFlagsDirectionVertical) {
				boundingBox->X += (FrameHeight - MaxY);
			} else {
				boundingBox->Y += (FrameHeight - MaxY);
			}
			break;
		}

		switch (AlignHorz) {
		case StringAlignmentCenter:
			if (format->formatFlags & StringFormatFlagsDirectionVertical) {
				boundingBox->Y += (FrameWidth - MaxX) * 0.5;
			} else {
				boundingBox->X += (FrameWidth - MaxX) * 0.5;
			}
			break;
		case StringAlignmentFar:
			if (format->formatFlags & StringFormatFlagsDirectionVertical) {
				boundingBox->Y += (FrameWidth - MaxX);
			} else {
				boundingBox->X += (FrameWidth - MaxX);
			}
			break;
		}
	}

	if (codepointsFitted) {
		/* how many characters from the string can be drawn in the boundingBox (#76664) */
		double max_width = boundingBox ? (boundingBox->X + boundingBox->Width) : rc->X + min (MaxX, rc->Width);
		double max_height = boundingBox ? (boundingBox->Y + boundingBox->Height) : rc->Y + min (MaxY, rc->Height);
		int charactersFitted;
		for (charactersFitted = 0; charactersFitted < StringLen; charactersFitted++) {
			if ((StringDetails[charactersFitted].PosX + StringDetails[charactersFitted].Width) > max_width)
				break;
			if (StringDetails[charactersFitted].PosY + LineHeight > max_height)
				break;
		}
		*codepointsFitted = charactersFitted;
	}

	if (linesFilled) {
		/* how many *complete* lines fits in our calculated boundingBox */
		double height = (boundingBox) ? boundingBox->Height : min (MaxY, rc->Height);
		*linesFilled = floor (height / LineHeight);
	}

	if (AlignHorz != StringAlignmentNear || AlignVert != StringAlignmentNear) {
		// Update alignment
		int length = 0;
		int current_line_length = 0;
		for (i = 0; i < StringLen; i++) {
			if (i == current_line_length) {
				length = StringDetails[i].LineLen;
				current_line_length = min(length + i, StringLen);
			}

			switch (AlignHorz) {
			case StringAlignmentNear:
				break;
			case StringAlignmentCenter:
				if ((current_line_length == 1) || (StringDetails [current_line_length - 1].PosX > 0)) {
					StringDetails[i].PosX += (FrameWidth - StringDetails [current_line_length - 1].PosX -
						StringDetails [current_line_length - 1].Width) / 2;
				}
				break;
			case StringAlignmentFar:
				StringDetails[i].PosX += FrameWidth - StringDetails [current_line_length - 1].PosX -
					StringDetails [current_line_length - 1].Width;
				break;
			}

			switch (AlignVert) {
			case StringAlignmentNear:
				break;
			case StringAlignmentCenter:
				StringDetails[i].PosY += (FrameHeight - MaxY) / 2;
				break;
			case StringAlignmentFar:
				StringDetails[i].PosY += FrameHeight - MaxY;
				break;
			}
		}
	}

	/* if asked, supply extra data to be reused when drawing the same string */
	if (data) {
		data->align_horz = AlignHorz;
		data->align_vert = AlignVert;
		data->line_height = LineHeight;
		data->max_y = MaxY;
		data->descent = FontExtent.descent;
	}

	return Ok;
}
Exemple #17
0
/* 
 * render functions 
 */ 
static void
begin_render(DiaRenderer *self)
{
  DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (self);

  if (renderer->surface)
    renderer->cr = cairo_create (renderer->surface);
  else
    g_assert (renderer->cr);

  cairo_scale (renderer->cr, renderer->scale, renderer->scale);
  cairo_translate (renderer->cr, -renderer->dia->extents.left, -renderer->dia->extents.top);

  /* clear background */
  if (renderer->with_alpha)
    {
      cairo_set_operator (renderer->cr, CAIRO_OPERATOR_SOURCE);
      cairo_set_source_rgba (renderer->cr,
                             renderer->dia->bg_color.red, 
                             renderer->dia->bg_color.green, 
                             renderer->dia->bg_color.blue,
                             0.0);
    }
  else
    {
      cairo_set_source_rgba (renderer->cr,
                             renderer->dia->bg_color.red, 
                             renderer->dia->bg_color.green, 
                             renderer->dia->bg_color.blue,
                             1.0);
    }
  cairo_paint (renderer->cr);
  if (renderer->with_alpha)
    {
      /* restore to default drawing */
      cairo_set_operator (renderer->cr, CAIRO_OPERATOR_OVER);
      cairo_set_source_rgba (renderer->cr,
                             renderer->dia->bg_color.red, 
                             renderer->dia->bg_color.green, 
                             renderer->dia->bg_color.blue,
                             1.0);
    }
#ifdef HAVE_PANGOCAIRO_H
  if (!renderer->layout)
    renderer->layout = pango_cairo_create_layout (renderer->cr);
#endif

  cairo_set_fill_rule (renderer->cr, CAIRO_FILL_RULE_EVEN_ODD);

#if 0 /* try to work around bug #341481 - no luck */
  {
    cairo_font_options_t *fo = cairo_font_options_create ();
    cairo_get_font_options (renderer->cr, fo);
    /* try to switch off kerning */
    cairo_font_options_set_hint_style (fo, CAIRO_HINT_STYLE_NONE);
    cairo_font_options_set_hint_metrics (fo, CAIRO_HINT_METRICS_OFF);

    cairo_set_font_options (renderer->cr, fo);
    cairo_font_options_destroy (fo);
#ifdef HAVE_PANGOCAIRO_H
    pango_cairo_update_context (renderer->cr, pango_layout_get_context (renderer->layout));
    pango_layout_context_changed (renderer->layout);
#endif
  }
#endif
  
  DIAG_STATE(renderer->cr)
}
Exemple #18
0
int main(int argc, char * argv[])
{
  double width = 320, height = 240;
  double f, delta = 0.125;
  cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
  cairo_t *crc = cairo_create(surface);
  cairo_text_extents_t extents;
  cairo_font_options_t* font;

  // Set up font  (face is second field in 'xlsfonts'; first field is foundry)
  font = cairo_font_options_create();
  cairo_font_options_set_antialias(font, CAIRO_ANTIALIAS_SUBPIXEL);
  cairo_set_font_options(crc, font);
  cairo_select_font_face(crc, "nimbus sans l", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
  cairo_set_font_size(crc, 16);
  cairo_font_options_destroy(font);

  // Background
  cairo_rectangle(crc, 0, 0, width, height);
  cairo_set_source_rgb(crc, 1, 1, 1);
  cairo_fill(crc);

  // Fill
  cairo_move_to(crc, 0, 220);
  for (f = -4; f < 4; f += delta) {
    double v = exp(-f * f / 2) / sqrt(2 * M_PI);
    cairo_line_to(crc, width * (f + 4) / 8, 220 - v * height);
  }
  cairo_close_path(crc);
  cairo_set_source_rgb(crc, 122 / 255.0, 143 / 255.0, 248 / 255.0);
  cairo_fill(crc);

  // Graph
  cairo_move_to(crc, 0, 220);
  for (f = -4; f < 4; f += delta) {
    double v = exp(-f * f / 2) / sqrt(2 * M_PI);
    cairo_line_to(crc, width * (f + 4) / 8, 220 - v * height);
  }
  cairo_set_line_width(crc, 2);
  cairo_set_source_rgb(crc, 7 / 255.0, 16 / 255.0, 141 / 255.0);
  cairo_stroke(crc);

  // Vertical Axis
  cairo_set_source_rgb(crc, 0, 0, 0);
  cairo_move_to(crc, width / 2, 0);
  cairo_line_to(crc, width / 2, height);
  cairo_stroke(crc);

  // Horizontal Axis
  cairo_move_to(crc, 0, 220);
  cairo_line_to(crc, width, 220);
  cairo_stroke(crc);

  // Horizontal Ticks
  cairo_set_line_width(crc, 1);
  for (f = -4; f < 4; f++) {
    cairo_move_to(crc, width * (f + 4) / 8, 220 - 5);
    cairo_line_to(crc, width * (f + 4) / 8, 220 + 5);
    cairo_stroke(crc);

    if (f > -4 && f != 0 && f < +4) {
      char str[] = "+3";
      if (f > 0)
	sprintf(str, "%d", (int) f);
      else
	sprintf(str, "%d", (int) f);
      cairo_text_extents(crc, str, &extents);
      cairo_move_to(crc, width * (f + 4) / 8 - extents.width / 2, 220 + 7 + extents.height);
      cairo_show_text(crc, str);
    }
  }

  // Vertical Ticks
  for (f = +1; f >= -1; f -= 0.1) {
    cairo_move_to(crc, width / 2 - 5, 220 + f * height);
    cairo_line_to(crc, width / 2 + 5, 220 + f * height);
    cairo_stroke(crc);
  }

  cairo_text_extents(crc, "0.5", &extents);
  cairo_move_to(crc, width / 2 + 7, 220 - 0.5 * height + extents.height / 2);
  cairo_show_text(crc, "0.5");

  cairo_surface_write_to_png(surface, "gauss.png");
  return 0;
}
Exemple #19
0
/* 
 * render functions 
 */ 
static void
begin_render(DiaRenderer *self, const Rectangle *update)
{
  DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (self);
  real onedu = 0.0;
  real lmargin = 0.0, tmargin = 0.0;
  gboolean paginated = renderer->surface && /* only with our own pagination, not GtkPrint */
    cairo_surface_get_type (renderer->surface) == CAIRO_SURFACE_TYPE_PDF && !renderer->skip_show_page;

  if (renderer->surface && !renderer->cr)
    renderer->cr = cairo_create (renderer->surface);
  else
    g_assert (renderer->cr);

  /* remember current state, so we can start from new with every page */
  cairo_save (renderer->cr);

  if (paginated && renderer->dia) {
    DiagramData *data = renderer->dia;
    /* Dia's paper.width already contains the scale, cairo needs it without 
     * Similar for margins, Dia's without, but cairo wants them?
     */
    real width = (data->paper.lmargin + data->paper.width * data->paper.scaling + data->paper.rmargin)
          * (72.0 / 2.54) + 0.5;
    real height = (data->paper.tmargin + data->paper.height * data->paper.scaling + data->paper.bmargin)
           * (72.0 / 2.54) + 0.5;
    /* "Changes the size of a PDF surface for the current (and
     * subsequent) pages." Pagination setup? */
    cairo_pdf_surface_set_size (renderer->surface, width, height);
    lmargin = data->paper.lmargin / data->paper.scaling;
    tmargin = data->paper.tmargin / data->paper.scaling;
  }

  cairo_scale (renderer->cr, renderer->scale, renderer->scale);
  /* to ensure no clipping at top/left we need some extra gymnastics,
   * otherwise a box with a line witdh one one pixel might loose the
   * top/left border as in bug #147386 */
  ensure_minimum_one_device_unit (renderer, &onedu);

  if (update && paginated) {
    cairo_rectangle (renderer->cr, lmargin, tmargin,
                     update->right - update->left, update->bottom - update->top);
    cairo_clip (renderer->cr);
    cairo_translate (renderer->cr, -update->left + lmargin, -update->top + tmargin);
  } else
    cairo_translate (renderer->cr, -renderer->dia->extents.left + onedu, -renderer->dia->extents.top + onedu);
  /* no more blurred UML diagrams */
  cairo_set_antialias (renderer->cr, CAIRO_ANTIALIAS_NONE);

  /* clear background */
  if (renderer->with_alpha)
    {
      cairo_set_operator (renderer->cr, CAIRO_OPERATOR_SOURCE);
      cairo_set_source_rgba (renderer->cr,
                             renderer->dia->bg_color.red, 
                             renderer->dia->bg_color.green, 
                             renderer->dia->bg_color.blue,
                             0.0);
    }
  else
    {
      cairo_set_source_rgba (renderer->cr,
                             renderer->dia->bg_color.red, 
                             renderer->dia->bg_color.green, 
                             renderer->dia->bg_color.blue,
                             1.0);
    }
  cairo_paint (renderer->cr);
  if (renderer->with_alpha)
    {
      /* restore to default drawing */
      cairo_set_operator (renderer->cr, CAIRO_OPERATOR_OVER);
      cairo_set_source_rgba (renderer->cr,
                             renderer->dia->bg_color.red, 
                             renderer->dia->bg_color.green, 
                             renderer->dia->bg_color.blue,
                             1.0);
    }
#ifdef HAVE_PANGOCAIRO_H
  if (!renderer->layout)
    renderer->layout = pango_cairo_create_layout (renderer->cr);
#endif

  cairo_set_fill_rule (renderer->cr, CAIRO_FILL_RULE_EVEN_ODD);

#if 0 /* try to work around bug #341481 - no luck */
  {
    cairo_font_options_t *fo = cairo_font_options_create ();
    cairo_get_font_options (renderer->cr, fo);
    /* try to switch off kerning */
    cairo_font_options_set_hint_style (fo, CAIRO_HINT_STYLE_NONE);
    cairo_font_options_set_hint_metrics (fo, CAIRO_HINT_METRICS_OFF);

    cairo_set_font_options (renderer->cr, fo);
    cairo_font_options_destroy (fo);
#ifdef HAVE_PANGOCAIRO_H
    pango_cairo_update_context (renderer->cr, pango_layout_get_context (renderer->layout));
    pango_layout_context_changed (renderer->layout);
#endif
  }
#endif
  
  DIAG_STATE(renderer->cr)
}
Exemple #20
0
bool
TextPainter::prepareBuffer() {

	if (_cairoWidth <= 0 || _cairoHeight <= 0)
		return false;

	if (_context)
		cairo_destroy(_context);

	if (_surface)
		cairo_surface_destroy(_surface);

	// ensure a valid opengl context
	OpenGl::Guard guard;

	// bind buffer for writing
	glCheck(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, _buf));

	// discard previous buffer (so we don't have to wait for GPU until we can
	// map) and create new buffer
	glCheck(glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, _cairoWidth*_cairoHeight*sizeof(cairo_pixel_t), 0, GL_DYNAMIC_DRAW));

	// bind buffer for reading
	glCheck(glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, _buf));

	LOG_ALL(textpainterlog) << "determine raster position of "
	                        << _glRoi.minX + 1.0/_lastResolution.x << ", "
	                        << _glRoi.maxY - 1.0/_lastResolution.y << " [gl]" << std::endl;

	// get the window coordinates of the lower-left corner of the rectangle we
	// want to draw to
	int r[4];
	glCheck(glRasterPos2f(_glRoi.minX + 1.0/_lastResolution.x, _glRoi.maxY - 1.0/_lastResolution.y));
	glCheck(glGetIntegerv(GL_CURRENT_RASTER_POSITION, r));
	_rasterPos.x = r[0];
	_rasterPos.y = r[1];

	LOG_ALL(textpainterlog) << "read content from raster position " << _rasterPos << std::endl;

	// load current content to buffer
	glCheck(glReadPixels(
			_rasterPos.x,
			_rasterPos.y,
			_cairoWidth,
			_cairoHeight,
			detail::pixel_format_traits<cairo_pixel_t>::gl_format,
			detail::pixel_format_traits<cairo_pixel_t>::gl_type,
			0));

	// map the pixel buffer object
	unsigned char* p = (unsigned char*)glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB);

	// wrap the buffer in a cairo surface
	_surface =
			cairo_image_surface_create_for_data(
					p,
					CAIRO_FORMAT_ARGB32,
					_cairoWidth,
					_cairoHeight,
					cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, _cairoWidth));

	// create a context for the surface
	_context = cairo_create(_surface);

	// set antialiasing options
	cairo_set_font_options(_context, _fontOptions);

	return true;
}
Exemple #21
0
static cairo_test_status_t
draw (cairo_t *cr, int width, int height)
{
    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
    FcPattern *pattern;
    cairo_font_face_t *font_face;
    cairo_font_extents_t font_extents;
    cairo_font_options_t *font_options;
    cairo_status_t status;
    char *filename;
    int face_count;
    struct stat stat_buf;

    xasprintf (&filename, "%s/%s", ctx->srcdir, FONT);

    if (stat (filename, &stat_buf) || ! S_ISREG (stat_buf.st_mode)) {
	cairo_test_log (ctx, "Error finding font: %s: file not found?\n", filename);
	return CAIRO_TEST_FAILURE;
    }

    pattern = FcFreeTypeQuery ((unsigned char *)filename, 0, NULL, &face_count);
    free (filename);
    if (! pattern) {
	cairo_test_log (ctx, "FcFreeTypeQuery failed.\n");
	return cairo_test_status_from_status (ctx, CAIRO_STATUS_NO_MEMORY);
    }

    font_face = cairo_ft_font_face_create_for_pattern (pattern);
    FcPatternDestroy (pattern);

    status = cairo_font_face_status (font_face);
    if (status) {
	cairo_test_log (ctx, "Error creating font face for %s: %s\n",
			filename,
			cairo_status_to_string (status));
	return cairo_test_status_from_status (ctx, status);
    }

    if (cairo_font_face_get_type (font_face) != CAIRO_FONT_TYPE_FT) {
	cairo_test_log (ctx, "Unexpected value from cairo_font_face_get_type: %d (expected %d)\n",
			cairo_font_face_get_type (font_face), CAIRO_FONT_TYPE_FT);
	cairo_font_face_destroy (font_face);
	return CAIRO_TEST_FAILURE;
    }

    cairo_set_font_face (cr, font_face);
    cairo_font_face_destroy (font_face);

    font_options = cairo_font_options_create ();

#define CHECK_FONT_EXTENTS(comment) do {\
    cairo_test_status_t test_status; \
    test_status = check_font_extents (ctx, cr, (comment)); \
    if (test_status != CAIRO_TEST_SUCCESS) { \
	cairo_font_options_destroy (font_options); \
	return test_status; \
    } \
} while (0)

    cairo_font_extents (cr, &font_extents);
    CHECK_FONT_EXTENTS ("default");

    cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_ON);
    cairo_set_font_options (cr, font_options);

    CHECK_FONT_EXTENTS ("HINT_METRICS_ON");

    cairo_move_to (cr, 1, font_extents.ascent - 1);
    cairo_set_source_rgb (cr, 0.0, 0.0, 1.0); /* blue */

    cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE);
    cairo_set_font_options (cr, font_options);
    CHECK_FONT_EXTENTS ("HINT_METRICS_ON HINT_STYLE_NONE");
    cairo_show_text (cr, "the ");

    cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_SLIGHT);
    cairo_set_font_options (cr, font_options);
    CHECK_FONT_EXTENTS ("HINT_METRICS_ON HINT_STYLE_SLIGHT");
    cairo_show_text (cr, "quick ");

    cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_MEDIUM);
    cairo_set_font_options (cr, font_options);
    CHECK_FONT_EXTENTS ("HINT_METRICS_ON HINT_STYLE_MEDIUM");
    cairo_show_text (cr, "brown");

    cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_FULL);
    cairo_set_font_options (cr, font_options);
    CHECK_FONT_EXTENTS ("HINT_METRICS_ON HINT_STYLE_FULL");
    cairo_show_text (cr, " fox");

    /* Switch from show_text to text_path/fill to exercise bug #7889 */
    cairo_text_path (cr, " jumps over a lazy dog");
    cairo_fill (cr);

    /* And test it rotated as well for the sake of bug #7888 */

    cairo_translate (cr, width, height);
    cairo_rotate (cr, M_PI);

    cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_DEFAULT);
    cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_OFF);
    cairo_set_font_options (cr, font_options);
    CHECK_FONT_EXTENTS ("HINT_METRICS_OFF");

    cairo_move_to (cr, 1, font_extents.height - font_extents.descent - 1);

    cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE);
    cairo_set_font_options (cr, font_options);
    CHECK_FONT_EXTENTS ("HINT_METRICS_OFF HINT_STYLE_NONE");
    cairo_show_text (cr, "the ");

    cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_SLIGHT);
    cairo_set_font_options (cr, font_options);
    CHECK_FONT_EXTENTS ("HINT_METRICS_OFF HINT_STYLE_SLIGHT");
    cairo_show_text (cr, "quick");

    cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_MEDIUM);
    cairo_set_font_options (cr, font_options);
    CHECK_FONT_EXTENTS ("HINT_METRICS_OFF HINT_STYLE_MEDIUM");
    cairo_show_text (cr, " brown");

    cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_FULL);
    cairo_set_font_options (cr, font_options);
    CHECK_FONT_EXTENTS ("HINT_METRICS_OFF HINT_STYLE_FULL");
    cairo_show_text (cr, " fox");

    cairo_text_path (cr, " jumps over");
    cairo_text_path (cr, " a lazy dog");
    cairo_fill (cr);

    cairo_font_options_destroy (font_options);

    return CAIRO_TEST_SUCCESS;
}
Exemple #22
0
static cairo_test_status_t
cairo_test_for_target (cairo_test_context_t		 *ctx,
		       const cairo_boilerplate_target_t	 *target,
		       int				  dev_offset,
		       cairo_bool_t                       similar)
{
    cairo_test_status_t status;
    cairo_surface_t *surface = NULL;
    cairo_t *cr;
    const char *empty_str = "";
    char *offset_str;
    char *base_name, *base_path;
    char *out_png_path;
    char *ref_path = NULL, *ref_png_path, *cmp_png_path = NULL;
    char *new_path = NULL, *new_png_path;
    char *xfail_path = NULL, *xfail_png_path;
    char *base_ref_png_path;
    char *base_new_png_path;
    char *base_xfail_png_path;
    char *diff_png_path;
    char *test_filename = NULL, *pass_filename = NULL, *fail_filename = NULL;
    cairo_test_status_t ret;
    cairo_content_t expected_content;
    cairo_font_options_t *font_options;
    const char *format;
    cairo_bool_t have_output = FALSE;
    cairo_bool_t have_result = FALSE;
    void *closure;
    double width, height;
    cairo_bool_t have_output_dir;
#if HAVE_MEMFAULT
    int malloc_failure_iterations = ctx->malloc_failure;
    int last_fault_count = 0;
#endif

    /* Get the strings ready that we'll need. */
    format = cairo_boilerplate_content_name (target->content);
    if (dev_offset)
	xasprintf (&offset_str, ".%d", dev_offset);
    else
	offset_str = (char *) empty_str;

    xasprintf (&base_name, "%s.%s.%s%s%s",
	       ctx->test_name,
	       target->name,
	       format,
	       similar ? ".similar" : "",
	       offset_str);

    if (offset_str != empty_str)
      free (offset_str);

    ref_png_path = cairo_test_reference_filename (ctx,
						  base_name,
						  ctx->test_name,
						  target->name,
						  target->basename,
						  format,
						  CAIRO_TEST_REF_SUFFIX,
						  CAIRO_TEST_PNG_EXTENSION);
    new_png_path = cairo_test_reference_filename (ctx,
						  base_name,
						  ctx->test_name,
						  target->name,
						  target->basename,
						  format,
						  CAIRO_TEST_NEW_SUFFIX,
						  CAIRO_TEST_PNG_EXTENSION);
    xfail_png_path = cairo_test_reference_filename (ctx,
						    base_name,
						    ctx->test_name,
						    target->name,
						    target->basename,
						    format,
						    CAIRO_TEST_XFAIL_SUFFIX,
						    CAIRO_TEST_PNG_EXTENSION);

    base_ref_png_path = cairo_test_reference_filename (ctx,
						  base_name,
						  ctx->test_name,
						  NULL, NULL,
						  format,
						  CAIRO_TEST_REF_SUFFIX,
						  CAIRO_TEST_PNG_EXTENSION);
    base_new_png_path = cairo_test_reference_filename (ctx,
						  base_name,
						  ctx->test_name,
						  NULL, NULL,
						  format,
						  CAIRO_TEST_NEW_SUFFIX,
						  CAIRO_TEST_PNG_EXTENSION);
    base_xfail_png_path = cairo_test_reference_filename (ctx,
						    base_name,
						    ctx->test_name,
						    NULL, NULL,
						    format,
						    CAIRO_TEST_XFAIL_SUFFIX,
						    CAIRO_TEST_PNG_EXTENSION);

    if (target->file_extension != NULL) {
	ref_path = cairo_test_reference_filename (ctx,
						  base_name,
						  ctx->test_name,
						  target->name,
						  target->basename,
						  format,
						  CAIRO_TEST_REF_SUFFIX,
						  target->file_extension);
	new_path = cairo_test_reference_filename (ctx,
						  base_name,
						  ctx->test_name,
						  target->name,
						  target->basename,
						  format,
						  CAIRO_TEST_NEW_SUFFIX,
						  target->file_extension);
	xfail_path = cairo_test_reference_filename (ctx,
						    base_name,
						    ctx->test_name,
						    target->name,
						    target->basename,
						    format,
						    CAIRO_TEST_XFAIL_SUFFIX,
						    target->file_extension);
    }

    have_output_dir = _cairo_test_mkdir (ctx->output);
    xasprintf (&base_path, "%s/%s",
	       have_output_dir ? ctx->output : ".",
	       base_name);
    xasprintf (&out_png_path, "%s" CAIRO_TEST_OUT_PNG, base_path);
    xasprintf (&diff_png_path, "%s" CAIRO_TEST_DIFF_PNG, base_path);

    if (ctx->test->requirements != NULL) {
	const char *required;

	required = target->is_vector ? "target=raster" : "target=vector";
	if (strstr (ctx->test->requirements, required) != NULL) {
	    cairo_test_log (ctx, "Error: Skipping for %s target %s\n",
			    target->is_vector ? "vector" : "raster",
			    target->name);
	    ret = CAIRO_TEST_UNTESTED;
	    goto UNWIND_STRINGS;
	}

	required = target->is_recording ? "target=!recording" : "target=recording";
	if (strstr (ctx->test->requirements, required) != NULL) {
	    cairo_test_log (ctx, "Error: Skipping for %s target %s\n",
			    target->is_recording ? "recording" : "non-recording",
			    target->name);
	    ret = CAIRO_TEST_UNTESTED;
	    goto UNWIND_STRINGS;
	}
    }

    width = ctx->test->width;
    height = ctx->test->height;
    if (width && height) {
	width += dev_offset;
	height += dev_offset;
    }

#if HAVE_MEMFAULT
REPEAT:
    MEMFAULT_CLEAR_FAULTS ();
    MEMFAULT_RESET_LEAKS ();
    ctx->last_fault_count = 0;
    last_fault_count = MEMFAULT_COUNT_FAULTS ();

    /* Pre-initialise fontconfig so that the configuration is loaded without
     * malloc failures (our primary goal is to test cairo fault tolerance).
     */
#if HAVE_FCINIT
    FcInit ();
#endif

    MEMFAULT_ENABLE_FAULTS ();
#endif
    have_output = FALSE;
    have_result = FALSE;

    /* Run the actual drawing code. */
    ret = CAIRO_TEST_SUCCESS;
    surface = (target->create_surface) (base_path,
					target->content,
					width, height,
					ctx->test->width + 25 * NUM_DEVICE_OFFSETS,
					ctx->test->height + 25 * NUM_DEVICE_OFFSETS,
					CAIRO_BOILERPLATE_MODE_TEST,
					&closure);
    if (surface == NULL) {
	cairo_test_log (ctx, "Error: Failed to set %s target\n", target->name);
	ret = CAIRO_TEST_UNTESTED;
	goto UNWIND_STRINGS;
    }

#if HAVE_MEMFAULT
    if (ctx->malloc_failure &&
	MEMFAULT_COUNT_FAULTS () - last_fault_count > 0 &&
	cairo_surface_status (surface) == CAIRO_STATUS_NO_MEMORY)
    {
	goto REPEAT;
    }
#endif

    if (cairo_surface_status (surface)) {
	MF (MEMFAULT_PRINT_FAULTS ());
	cairo_test_log (ctx, "Error: Created an error surface: %s\n",
			cairo_status_to_string (cairo_surface_status (surface)));
	ret = CAIRO_TEST_FAILURE;
	goto UNWIND_STRINGS;
    }

    /* Check that we created a surface of the expected type. */
    if (cairo_surface_get_type (surface) != target->expected_type) {
	MF (MEMFAULT_PRINT_FAULTS ());
	cairo_test_log (ctx, "Error: Created surface is of type %d (expected %d)\n",
			cairo_surface_get_type (surface), target->expected_type);
	ret = CAIRO_TEST_UNTESTED;
	goto UNWIND_SURFACE;
    }

    /* Check that we created a surface of the expected content,
     * (ignore the artificial CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED value).
     */
    expected_content = cairo_boilerplate_content (target->content);

    if (cairo_surface_get_content (surface) != expected_content) {
	MF (MEMFAULT_PRINT_FAULTS ());
	cairo_test_log (ctx, "Error: Created surface has content %d (expected %d)\n",
			cairo_surface_get_content (surface), expected_content);
	ret = CAIRO_TEST_FAILURE;
	goto UNWIND_SURFACE;
    }

    if (cairo_surface_set_user_data (surface,
				     &cairo_boilerplate_output_basename_key,
				     base_path,
				     NULL))
    {
#if HAVE_MEMFAULT
	cairo_surface_destroy (surface);

	if (target->cleanup)
	    target->cleanup (closure);

	goto REPEAT;
#else
	ret = CAIRO_TEST_FAILURE;
	goto UNWIND_SURFACE;
#endif
    }

    cairo_surface_set_device_offset (surface, dev_offset, dev_offset);

    cr = cairo_create (surface);
    if (cairo_set_user_data (cr, &_cairo_test_context_key, (void*) ctx, NULL)) {
#if HAVE_MEMFAULT
	cairo_destroy (cr);
	cairo_surface_destroy (surface);

	if (target->cleanup)
	    target->cleanup (closure);

	goto REPEAT;
#else
	ret = CAIRO_TEST_FAILURE;
	goto UNWIND_CAIRO;
#endif
    }

    if (similar)
	cairo_push_group_with_content (cr, expected_content);

    /* Clear to transparent (or black) depending on whether the target
     * surface supports alpha. */
    cairo_save (cr);
    cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
    cairo_paint (cr);
    cairo_restore (cr);

    /* Set all components of font_options to avoid backend differences
     * and reduce number of needed reference images. */
    font_options = cairo_font_options_create ();
    cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE);
    cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_ON);
    cairo_font_options_set_antialias (font_options, CAIRO_ANTIALIAS_GRAY);
    cairo_set_font_options (cr, font_options);
    cairo_font_options_destroy (font_options);

    cairo_save (cr);
    alarm (ctx->timeout);
    status = (ctx->test->draw) (cr, ctx->test->width, ctx->test->height);
    alarm (0);
    cairo_restore (cr);

    if (similar) {
	cairo_pop_group_to_source (cr);
	cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
	cairo_paint (cr);
    }

#if HAVE_MEMFAULT
    MEMFAULT_DISABLE_FAULTS ();

    /* repeat test after malloc failure injection */
    if (ctx->malloc_failure &&
	MEMFAULT_COUNT_FAULTS () - last_fault_count > 0 &&
	(status == CAIRO_TEST_NO_MEMORY ||
	 cairo_status (cr) == CAIRO_STATUS_NO_MEMORY ||
	 cairo_surface_status (surface) == CAIRO_STATUS_NO_MEMORY))
    {
	cairo_destroy (cr);
	cairo_surface_destroy (surface);
	if (target->cleanup)
	    target->cleanup (closure);
	cairo_debug_reset_static_data ();
#if HAVE_FCFINI
	FcFini ();
#endif
	if (MEMFAULT_COUNT_LEAKS () > 0) {
	    MEMFAULT_PRINT_FAULTS ();
	    MEMFAULT_PRINT_LEAKS ();
	}

	goto REPEAT;
    }
#endif

    /* Then, check all the different ways it could fail. */
    if (status) {
	cairo_test_log (ctx, "Error: Function under test failed\n");
	ret = status;
	goto UNWIND_CAIRO;
    }

#if HAVE_MEMFAULT
    if (MEMFAULT_COUNT_FAULTS () - last_fault_count > 0 &&
	MEMFAULT_HAS_FAULTS ())
    {
	VALGRIND_PRINTF ("Unreported memfaults...");
	MEMFAULT_PRINT_FAULTS ();
    }
#endif

    if (target->finish_surface != NULL) {
#if HAVE_MEMFAULT
	/* We need to re-enable faults as most recording-surface processing
	 * is done during cairo_surface_finish().
	 */
	MEMFAULT_CLEAR_FAULTS ();
	last_fault_count = MEMFAULT_COUNT_FAULTS ();
	MEMFAULT_ENABLE_FAULTS ();
#endif

	/* also check for infinite loops whilst replaying */
	alarm (ctx->timeout);
	status = target->finish_surface (surface);
	alarm (0);

#if HAVE_MEMFAULT
	MEMFAULT_DISABLE_FAULTS ();

	if (ctx->malloc_failure &&
	    MEMFAULT_COUNT_FAULTS () - last_fault_count > 0 &&
	    status == CAIRO_STATUS_NO_MEMORY)
	{
	    cairo_destroy (cr);
	    cairo_surface_destroy (surface);
	    if (target->cleanup)
		target->cleanup (closure);
	    cairo_debug_reset_static_data ();
#if HAVE_FCFINI
	    FcFini ();
#endif
	    if (MEMFAULT_COUNT_LEAKS () > 0) {
		MEMFAULT_PRINT_FAULTS ();
		MEMFAULT_PRINT_LEAKS ();
	    }

	    goto REPEAT;
	}
#endif
	if (status) {
	    cairo_test_log (ctx, "Error: Failed to finish surface: %s\n",
			    cairo_status_to_string (status));
	    ret = CAIRO_TEST_FAILURE;
	    goto UNWIND_CAIRO;
	}
    }

    /* Skip image check for tests with no image (width,height == 0,0) */
    if (ctx->test->width != 0 && ctx->test->height != 0) {
	cairo_surface_t *ref_image;
	cairo_surface_t *test_image;
	cairo_surface_t *diff_image;
	buffer_diff_result_t result;
	cairo_status_t diff_status;

	if (ref_png_path == NULL) {
	    cairo_test_log (ctx, "Error: Cannot find reference image for %s\n",
			    base_name);

	    /* we may be running this test to generate reference images */
	    _xunlink (ctx, out_png_path);
	    /* be more generous as we may need to use external renderers */
	    alarm (4 * ctx->timeout);
	    test_image = target->get_image_surface (surface, 0,
		                                    ctx->test->width,
						    ctx->test->height);
	    alarm (0);
	    diff_status = cairo_surface_write_to_png (test_image, out_png_path);
	    cairo_surface_destroy (test_image);
	    if (diff_status) {
		if (cairo_surface_status (test_image) == CAIRO_STATUS_INVALID_STATUS)
		    ret = CAIRO_TEST_CRASHED;
		else
		    ret = CAIRO_TEST_FAILURE;
		cairo_test_log (ctx,
			        "Error: Failed to write output image: %s\n",
			        cairo_status_to_string (diff_status));
	    }
	    have_output = TRUE;

	    ret = CAIRO_TEST_XFAILURE;
	    goto UNWIND_CAIRO;
	}

	if (target->file_extension != NULL) { /* compare vector surfaces */
	    char *filenames[] = {
		ref_png_path,
		ref_path,
		new_png_path,
		new_path,
		xfail_png_path,
		xfail_path,
		base_ref_png_path,
		base_new_png_path,
		base_xfail_png_path,
	    };

	    xasprintf (&test_filename, "%s.out%s",
		       base_path, target->file_extension);
	    xasprintf (&pass_filename, "%s.pass%s",
		       base_path, target->file_extension);
	    xasprintf (&fail_filename, "%s.fail%s",
		       base_path, target->file_extension);

	    if (cairo_test_file_is_older (pass_filename,
					  filenames,
					  ARRAY_SIZE (filenames)))
	    {
		_xunlink (ctx, pass_filename);
	    }
	    if (cairo_test_file_is_older (fail_filename,
					  filenames,
					  ARRAY_SIZE (filenames)))
	    {
		_xunlink (ctx, fail_filename);
	    }

	    if (cairo_test_files_equal (out_png_path, ref_path)) {
		cairo_test_log (ctx, "Vector surface matches reference.\n");
		have_output = FALSE;
		ret = CAIRO_TEST_SUCCESS;
		goto UNWIND_CAIRO;
	    }
	    if (cairo_test_files_equal (out_png_path, new_path)) {
		cairo_test_log (ctx, "Vector surface matches current failure.\n");
		have_output = FALSE;
		ret = CAIRO_TEST_NEW;
		goto UNWIND_CAIRO;
	    }
	    if (cairo_test_files_equal (out_png_path, xfail_path)) {
		cairo_test_log (ctx, "Vector surface matches known failure.\n");
		have_output = FALSE;
		ret = CAIRO_TEST_XFAILURE;
		goto UNWIND_CAIRO;
	    }

	    if (cairo_test_files_equal (test_filename, pass_filename)) {
		/* identical output as last known PASS */
		cairo_test_log (ctx, "Vector surface matches last pass.\n");
		have_output = TRUE;
		ret = CAIRO_TEST_SUCCESS;
		goto UNWIND_CAIRO;
	    }
	    if (cairo_test_files_equal (test_filename, fail_filename)) {
		/* identical output as last known FAIL, fail */
		cairo_test_log (ctx, "Vector surface matches last fail.\n");
		have_result = TRUE; /* presume these were kept around as well */
		have_output = TRUE;
		ret = CAIRO_TEST_FAILURE;
		goto UNWIND_CAIRO;
	    }
	}

	/* be more generous as we may need to use external renderers */
	alarm (4 * ctx->timeout);
	test_image = target->get_image_surface (surface, 0,
					        ctx->test->width,
						ctx->test->height);
	alarm (0);
	if (cairo_surface_status (test_image)) {
	    cairo_test_log (ctx, "Error: Failed to extract image: %s\n",
			    cairo_status_to_string (cairo_surface_status (test_image)));
	    if (cairo_surface_status (test_image) == CAIRO_STATUS_INVALID_STATUS)
		ret = CAIRO_TEST_CRASHED;
	    else
		ret = CAIRO_TEST_FAILURE;
	    cairo_surface_destroy (test_image);
	    goto UNWIND_CAIRO;
	}

	_xunlink (ctx, out_png_path);
	diff_status = cairo_surface_write_to_png (test_image, out_png_path);
	if (diff_status) {
	    cairo_test_log (ctx, "Error: Failed to write output image: %s\n",
			    cairo_status_to_string (diff_status));
	    cairo_surface_destroy (test_image);
	    ret = CAIRO_TEST_FAILURE;
	    goto UNWIND_CAIRO;
	}
	have_output = TRUE;

	/* binary compare png files (no decompression) */
	if (target->file_extension == NULL) {
	    char *filenames[] = {
		ref_png_path,
		new_png_path,
		xfail_png_path,
		base_ref_png_path,
		base_new_png_path,
		base_xfail_png_path,
	    };

	    xasprintf (&test_filename, "%s", out_png_path);
	    xasprintf (&pass_filename, "%s.pass.png", base_path);
	    xasprintf (&fail_filename, "%s.fail.png", base_path);

	    if (cairo_test_file_is_older (pass_filename,
					  filenames,
					  ARRAY_SIZE (filenames)))
	    {
		_xunlink (ctx, pass_filename);
	    }
	    if (cairo_test_file_is_older (fail_filename,
					  filenames,
					  ARRAY_SIZE (filenames)))
	    {
		_xunlink (ctx, fail_filename);
	    }

	    if (cairo_test_files_equal (test_filename, pass_filename)) {
		cairo_test_log (ctx, "PNG file exactly matches last pass.\n");
                have_result = TRUE;
		cairo_surface_destroy (test_image);
		ret = CAIRO_TEST_SUCCESS;
		goto UNWIND_CAIRO;
	    }
	    if (cairo_test_files_equal (out_png_path, ref_png_path)) {
		cairo_test_log (ctx, "PNG file exactly matches reference image.\n");
                have_result = TRUE;
		cairo_surface_destroy (test_image);
		ret = CAIRO_TEST_SUCCESS;
		goto UNWIND_CAIRO;
	    }
	    if (cairo_test_files_equal (out_png_path, new_png_path)) {
		cairo_test_log (ctx, "PNG file exactly matches current failure image.\n");
                have_result = TRUE;
		cairo_surface_destroy (test_image);
		ret = CAIRO_TEST_NEW;
		goto UNWIND_CAIRO;
	    }
	    if (cairo_test_files_equal (out_png_path, xfail_png_path)) {
		cairo_test_log (ctx, "PNG file exactly matches known failure image.\n");
                have_result = TRUE;
		cairo_surface_destroy (test_image);
		ret = CAIRO_TEST_XFAILURE;
		goto UNWIND_CAIRO;
	    }
	    if (cairo_test_files_equal (test_filename, fail_filename)) {
		cairo_test_log (ctx, "PNG file exactly matches last fail.\n");
		have_result = TRUE; /* presume these were kept around as well */
		cairo_surface_destroy (test_image);
		ret = CAIRO_TEST_FAILURE;
		goto UNWIND_CAIRO;
	    }
	} else {
	    if (cairo_test_files_equal (out_png_path, ref_png_path)) {
		cairo_test_log (ctx, "PNG file exactly matches reference image.\n");
		have_result = TRUE;
		cairo_surface_destroy (test_image);
		ret = CAIRO_TEST_SUCCESS;
		goto UNWIND_CAIRO;
	    }
	    if (cairo_test_files_equal (out_png_path, new_png_path)) {
		cairo_test_log (ctx, "PNG file exactly matches current failure image.\n");
		have_result = TRUE;
		cairo_surface_destroy (test_image);
		ret = CAIRO_TEST_NEW;
		goto UNWIND_CAIRO;
	    }
	    if (cairo_test_files_equal (out_png_path, xfail_png_path)) {
		cairo_test_log (ctx, "PNG file exactly matches known failure image.\n");
		have_result = TRUE;
		cairo_surface_destroy (test_image);
		ret = CAIRO_TEST_XFAILURE;
		goto UNWIND_CAIRO;
	    }
	}

	if (cairo_test_files_equal (out_png_path, base_ref_png_path)) {
	    cairo_test_log (ctx, "PNG file exactly reference image.\n");
	    have_result = TRUE;
	    cairo_surface_destroy (test_image);
	    ret = CAIRO_TEST_SUCCESS;
	    goto UNWIND_CAIRO;
	}
	if (cairo_test_files_equal (out_png_path, base_new_png_path)) {
	    cairo_test_log (ctx, "PNG file exactly current failure image.\n");
	    have_result = TRUE;
	    cairo_surface_destroy (test_image);
	    ret = CAIRO_TEST_NEW;
	    goto UNWIND_CAIRO;
	}
	if (cairo_test_files_equal (out_png_path, base_xfail_png_path)) {
	    cairo_test_log (ctx, "PNG file exactly known failure image.\n");
	    have_result = TRUE;
	    cairo_surface_destroy (test_image);
	    ret = CAIRO_TEST_XFAILURE;
	    goto UNWIND_CAIRO;
	}

	/* first compare against the ideal reference */
	ref_image = cairo_test_get_reference_image (ctx, base_ref_png_path,
						    target->content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED);
	if (cairo_surface_status (ref_image)) {
	    cairo_test_log (ctx, "Error: Cannot open reference image for %s: %s\n",
			    base_ref_png_path,
			    cairo_status_to_string (cairo_surface_status (ref_image)));
	    cairo_surface_destroy (test_image);
	    ret = CAIRO_TEST_FAILURE;
	    goto UNWIND_CAIRO;
	}

	diff_image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
						 ctx->test->width,
						 ctx->test->height);

	cmp_png_path = base_ref_png_path;
	diff_status = image_diff (ctx,
				  test_image, ref_image, diff_image,
				  &result);
	_xunlink (ctx, diff_png_path);
	if (diff_status ||
            image_diff_is_failure (&result, target->error_tolerance))
	{
	    /* that failed, so check against the specific backend */
	    ref_image = cairo_test_get_reference_image (ctx, ref_png_path,
							target->content == CAIRO_TEST_CONTENT_COLOR_ALPHA_FLATTENED);
	    if (cairo_surface_status (ref_image)) {
		cairo_test_log (ctx, "Error: Cannot open reference image for %s: %s\n",
				ref_png_path,
				cairo_status_to_string (cairo_surface_status (ref_image)));
		cairo_surface_destroy (test_image);
		ret = CAIRO_TEST_FAILURE;
		goto UNWIND_CAIRO;
	    }

	    cmp_png_path = ref_png_path;
	    diff_status = image_diff (ctx,
				      test_image, ref_image,
				      diff_image,
				      &result);
	    if (diff_status)
	    {
		cairo_test_log (ctx, "Error: Failed to compare images: %s\n",
				cairo_status_to_string (diff_status));
		ret = CAIRO_TEST_FAILURE;
	    }
	    else if (image_diff_is_failure (&result, target->error_tolerance))
	    {
		ret = CAIRO_TEST_FAILURE;

		diff_status = cairo_surface_write_to_png (diff_image,
							  diff_png_path);
		if (diff_status) {
		    cairo_test_log (ctx, "Error: Failed to write differences image: %s\n",
				    cairo_status_to_string (diff_status));
		} else {
		    have_result = TRUE;
		}

		cairo_test_copy_file (test_filename, fail_filename);
	    }
	    else
	    { /* success */
		cairo_test_copy_file (test_filename, pass_filename);
	    }
	}
	else
	{ /* success */
	    cairo_test_copy_file (test_filename, pass_filename);
	}

	/* If failed, compare against the current image output,
	 * and attempt to detect systematic failures.
	 */
	if (ret == CAIRO_TEST_FAILURE) {
	    char *image_out_path;

	    image_out_path =
		cairo_test_reference_filename (ctx,
					       base_name,
					       ctx->test_name,
					       "image",
					       "image",
					       format,
					       CAIRO_TEST_OUT_SUFFIX,
					       CAIRO_TEST_PNG_EXTENSION);
	    if (image_out_path != NULL) {
		if (cairo_test_files_equal (out_png_path,
					    image_out_path))
		{
		    ret = CAIRO_TEST_XFAILURE;
		}
		else
		{
		    ref_image =
			cairo_image_surface_create_from_png (image_out_path);
		    if (cairo_surface_status (ref_image) == CAIRO_STATUS_SUCCESS)
		    {
			diff_status = image_diff (ctx,
						  test_image, ref_image,
						  diff_image,
						  &result);
			if (diff_status == CAIRO_STATUS_SUCCESS &&
			    !image_diff_is_failure (&result, target->error_tolerance))
			{
			    ret = CAIRO_TEST_XFAILURE;
			}

			cairo_surface_destroy (ref_image);
		    }
		}

		free (image_out_path);
	    }
	}

	cairo_surface_destroy (test_image);
	cairo_surface_destroy (diff_image);
    }

    if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) {
	cairo_test_log (ctx, "Error: Function under test left cairo status in an error state: %s\n",
			cairo_status_to_string (cairo_status (cr)));
	ret = CAIRO_TEST_ERROR;
	goto UNWIND_CAIRO;
    }

UNWIND_CAIRO:
    free (test_filename);
    free (fail_filename);
    free (pass_filename);

    test_filename = fail_filename = pass_filename = NULL;

#if HAVE_MEMFAULT
    if (ret == CAIRO_TEST_FAILURE)
	MEMFAULT_PRINT_FAULTS ();
#endif
    cairo_destroy (cr);
UNWIND_SURFACE:
    cairo_surface_destroy (surface);

    if (target->cleanup)
	target->cleanup (closure);

#if HAVE_MEMFAULT
    cairo_debug_reset_static_data ();

#if HAVE_FCFINI
    FcFini ();
#endif

    if (MEMFAULT_COUNT_LEAKS () > 0) {
	if (ret != CAIRO_TEST_FAILURE)
	    MEMFAULT_PRINT_FAULTS ();
	MEMFAULT_PRINT_LEAKS ();
    }

    if (ret == CAIRO_TEST_SUCCESS && --malloc_failure_iterations > 0)
	goto REPEAT;
#endif

    if (have_output)
	cairo_test_log (ctx, "OUTPUT: %s\n", out_png_path);

    if (have_result) {
	if (cmp_png_path == NULL) {
	    /* XXX presume we matched the normal ref last time */
	    cmp_png_path = ref_png_path;
	}
	cairo_test_log (ctx,
			"REFERENCE: %s\nDIFFERENCE: %s\n",
			cmp_png_path, diff_png_path);
    }

UNWIND_STRINGS:
    free (out_png_path);
    free (ref_png_path);
    free (base_ref_png_path);
    free (ref_path);
    free (new_png_path);
    free (base_new_png_path);
    free (new_path);
    free (xfail_png_path);
    free (base_xfail_png_path);
    free (xfail_path);
    free (diff_png_path);
    free (base_path);
    free (base_name);

    return ret;
}
Exemple #23
0
	void lime_cairo_set_font_options (double handle, double options) {
		
		cairo_set_font_options ((cairo_t*)(intptr_t)handle, (cairo_font_options_t*)(intptr_t)options);
		
	}
  void flush()
  {
    cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_A8, _totalWidth, _maxHeight);
    cairo_t *cr = cairo_create(surface);
    int pos = 0;
    cairo_set_source_rgba (cr, 0., 0., 0., 0);
    cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
    cairo_paint(cr);
    cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
    cairo_font_options_t *fontOptions = cairo_font_options_create();
    cairo_get_font_options(cr, fontOptions);
    cairo_font_options_set_hint_style(fontOptions, CAIRO_HINT_STYLE_FULL);
    cairo_font_options_set_antialias(fontOptions, CAIRO_ANTIALIAS_GRAY);
    cairo_set_font_options(cr, fontOptions);
    cairo_font_options_destroy(fontOptions);

    cairo_set_source_rgba(cr, 1, 1, 1, 1);
    for(std::vector<element>::iterator it = _elements.begin(); it != _elements.end();  ++it) {
      cairo_move_to(cr, pos - it->xBearing, -it->yBearing);
      cairo_set_font_size(cr, it->fontSize);
      cairo_set_font_face(cr, it->fontFace);
      cairo_show_text(cr, it->text.c_str());
      cairo_font_face_destroy(it->fontFace);
      pos += it->width;
    }
    cairo_destroy(cr);
    //setup matrices
    GLint matrixMode;
    GLuint textureId;
    glGetIntegerv (GL_MATRIX_MODE, &matrixMode);
    glMatrixMode (GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity ();
    glMatrixMode (GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity ();
    float winw = Fl_Window::current()->w();
    float winh = Fl_Window::current()->h();
    glScalef (2.0f / winw, 2.0f /  winh, 1.0f);
    glTranslatef (-winw / 2.0f, -winh / 2.0f, 0.0f);
    //write the texture on screen
    glEnable(GL_TEXTURE_RECTANGLE_ARB);
    glPushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT | GL_COLOR_BUFFER_BIT);
    glDisable(GL_LIGHTING);
    glDisable(GL_DEPTH_TEST);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glGenTextures(1, &textureId);
    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, textureId);
    glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_ALPHA,
                 cairo_image_surface_get_width(surface),
                 cairo_image_surface_get_height(surface), 0,
                 GL_ALPHA, GL_UNSIGNED_BYTE, cairo_image_surface_get_data(surface));
    //glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_SRC0_ALPHA);
    //printf("error %i %s\n", __LINE__, gluErrorString(glGetError()));
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

    pos = 0;
    for(std::vector<element>::iterator it = _elements.begin(); it != _elements.end();  ++it) {
      glTranslatef(it->x, it->y, it->z);
      glColor4f(it->r, it->g, it->b, it->alpha);
      int Lx = it->width;
      int Ly = it->height;

      glBegin (GL_QUADS);
      glTexCoord2f (pos, 0);
      glVertex2f (0.0f, Ly);
      glTexCoord2f (pos + Lx, 0);
      glVertex2f (Lx, Ly);
      glTexCoord2f (pos + Lx, Ly);
      glVertex2f (Lx, 0.0f);
      glTexCoord2f (pos, Ly);
      glVertex2f (0.0f, 0.0f);
      glEnd ();
      pos += Lx;
      glTranslatef(-it->x, -it->y, -it->z);
    }
    glDeleteTextures(1, &textureId);

    glPopAttrib();

    // reset original matrices
    glPopMatrix(); // GL_MODELVIEW
    glMatrixMode (GL_PROJECTION);
    glPopMatrix();
    glMatrixMode (matrixMode);
    _elements.clear();
    _maxHeight = 0;
    _totalWidth = 0;
    cairo_surface_destroy(surface);
  }
Exemple #25
0
TGUIFont *Alloc_GUIFont(const char *AFontName, float AHeight)
{
  TGUIFont *BFont = (TGUIFont *)malloc(sizeof(TGUIFont));
  BFont->FGridWidth = 0;
  BFont->FGridHeight = 0;
  BFont->FHeight = AHeight;
  BFont->FExtents = (TGUIFontExtent *)malloc(sizeof(TGUIFontExtent) * 256);
  TGUIFontExtent *BCharExtent = BFont->FExtents;
  cairo_text_extents_t *BExtents = (cairo_text_extents_t *)malloc(sizeof(cairo_text_extents_t));
  int BRow = 0;
  int BColumn = 0;
  GUIFont_GetGreaterSize(AFontName, AHeight, &BFont->FGridWidth, &BFont->FGridHeight);
  printf("[MESSAGE] Font grid of size (%i, %i).\n", BFont->FGridWidth, BFont->FGridHeight);
  BFont->FTextureWidth = Get_NextP2(BFont->FGridWidth * 16);
  BFont->FTextureHeight = Get_NextP2(BFont->FGridHeight * 16);
  printf("[MESSAGE] Font texture of size (%i, %i).\n", BFont->FTextureWidth, BFont->FTextureHeight);
  
  unsigned char *BData = NULL;
  unsigned char *BText = (unsigned char *)malloc(sizeof(unsigned char) * 2);
  BText[0] = 0;
  BText[1] = '\0';

  // Create texture data .
  cairo_surface_t *BSurface = cairo_image_surface_create(CAIRO_FORMAT_A8,
                                                         BFont->FTextureWidth,
                                                         BFont->FTextureHeight);
  cairo_t *BContext = cairo_create(BSurface);
  
  cairo_set_antialias(BContext, CAIRO_ANTIALIAS_NONE);
  cairo_set_operator(BContext, CAIRO_OPERATOR_OVER);
  cairo_set_source_rgba(BContext, 0.0, 0.0, 0.0, 0.0);
  
  cairo_font_options_t *cfo = cairo_font_options_create();
  cairo_font_options_set_antialias(cfo, CAIRO_ANTIALIAS_SUBPIXEL);
  cairo_set_font_options(BContext, cfo);
  cairo_set_source_rgba(BContext, 0.0, 0.0, 0.0, 1.0);
  cairo_select_font_face(BContext, AFontName, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
  cairo_set_font_size(BContext, AHeight);
  
  for (BText[0] = 0; BText[0] < 255; BText[0]++)
  {
    cairo_text_extents(BContext, BText, BExtents);
    if (BExtents)
    {
      BCharExtent->FAdvanceX = BExtents->x_advance;
      if (BText[0] == 32)
      {
        //BCharExtent->FAdvanceX = BFont->FGridWidth;
      };
      BCharExtent->FAdvanceY = BExtents->y_advance;
      BCharExtent->FBearingX = BExtents->x_bearing;
      BCharExtent->FBearingY = BExtents->y_bearing;
      BCharExtent->FWidth = BExtents->width;
      BCharExtent->FHeight = BExtents->height;
      BRow = BText[0] / 16;
      BColumn = BText[0] % 16;
      cairo_move_to(BContext, -BExtents->x_bearing + (BColumn * BFont->FGridWidth), -BExtents->y_bearing + (BRow * BFont->FGridHeight));
      cairo_show_text(BContext, BText);
    } else
    {
      printf("[MESSAGE] Fail to create font. Extents of char %i returned as null.\n", BText[0]);
      return NULL;
    };
    BCharExtent++;
  };
  cairo_surface_flush(BSurface);
  //cairo_surface_write_to_png(BSurface, "/home/felipefs/Desktop/texture.png");
  BData = cairo_image_surface_get_data(BSurface);
  glGenTextures(1, &BFont->FTexture);
  glBindTexture(GL_TEXTURE_2D, BFont->FTexture);
  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
  //glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  //glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, BFont->FTextureWidth, BFont->FTextureHeight,
               0, GL_ALPHA, GL_UNSIGNED_BYTE, BData);
  
  cairo_destroy(BContext);
  cairo_surface_destroy(BSurface);
  //free(BData);
  if (glIsTexture(BFont->FTexture) == GL_FALSE)
  {
    printf("[ERROR] Fail to create character texture of size %ix%i.\n", BFont->FTextureWidth, BFont->FTextureHeight);
  };
  printf("[MESSAGE] Font created.\n");
  return BFont;
};
Exemple #26
0
static cairo_time_t
do_glyphs (double font_size,
	   cairo_antialias_t antialias,
	   cairo_t *cr, int width, int height, int loops)
{
    const char text[] = "the jay, pig, fox, zebra and my wolves quack";
    cairo_scaled_font_t *scaled_font;
    cairo_glyph_t *glyphs = NULL, *glyphs_copy;
    cairo_text_extents_t extents;
    cairo_font_options_t *options;
    cairo_status_t status;
    double x, y;
    int num_glyphs, n;

    options = cairo_font_options_create ();
    cairo_font_options_set_antialias (options, antialias);
    cairo_set_font_options (cr, options);
    cairo_font_options_destroy (options);

    cairo_select_font_face (cr,
			    "@cairo:",
			    CAIRO_FONT_SLANT_NORMAL,
			    CAIRO_FONT_WEIGHT_NORMAL);
    cairo_set_font_size (cr, font_size);
    scaled_font = cairo_get_scaled_font (cr);
    status = cairo_scaled_font_text_to_glyphs (scaled_font, 0., 0.,
					       text, -1,
					       &glyphs, &num_glyphs,
					       NULL, NULL,
					       NULL);
    if (status)
	return 0;

    glyphs_copy = cairo_glyph_allocate (num_glyphs);
    if (glyphs_copy == NULL) {
	cairo_glyph_free (glyphs);
	return 0;
    }

    cairo_scaled_font_glyph_extents (scaled_font,
				     glyphs, num_glyphs,
				     &extents);

    cairo_perf_timer_start ();

    while (loops--) {
	y = 0;
	do {
	    x = 0;
	    do {
		for (n = 0; n < num_glyphs; n++) {
		    glyphs_copy[n] = glyphs[n];
		    glyphs_copy[n].x += x;
		    glyphs_copy[n].y += y;
		}
		cairo_show_glyphs (cr, glyphs_copy, num_glyphs);

		x += extents.width;
	    } while (x < width);
	    y += extents.height;
	} while (y < height);
    }

    cairo_perf_timer_stop ();

    cairo_glyph_free (glyphs);
    cairo_glyph_free (glyphs_copy);

    return cairo_perf_timer_elapsed ();
}
Exemple #27
0
	void lime_cairo_set_font_options (value handle, value options) {
		
		cairo_set_font_options ((cairo_t*)val_data (handle), (cairo_font_options_t*)val_data (options));
		
	}
Exemple #28
0
int main(int argc, char** argv) {

  int c;
  float col_r, col_g, col_b = -1.0f;
  Options opt;

  while ((c = getopt(argc, argv, "a:x:y:f:s:t:n:w:r:g:b:c:h:i:j:o:v")) != -1) {
    switch(c) {
      /* verbose */
      /* ------------------------------------------------------- */
      case 'v': {
        opt.verbose = 0;
        break;
      }

      /* color */
      /* ------------------------------------------------------- */
      case 'r': {
        col_r = convert_type<float>(optarg);
        break;
      }
      case 'g': {
        col_g = convert_type<float>(optarg);
        break;
      }
      case 'b': {
        col_b = convert_type<float>(optarg);
        break;
      }

      /* ------------------------------------------------------- */
      /* hashtag */
      case 'h': {
        opt.hashtag = convert_type<std::string>(optarg);
        break;
      }
      case 'i': {
        opt.hashtag_x = convert_type<int>(optarg);
        break;
      }
      case 'j': {
        opt.hashtag_y = convert_type<int>(optarg);
        break;
      }
      
      /* ------------------------------------------------------- */
      /* foreground */
      case 'c': {
        opt.foreground_file = convert_type<std::string>(optarg);
        break;
      }
      /* ------------------------------------------------------- */
      /* background */
      case 'x': {
        opt.background_x = convert_type<int>(optarg);
        break;
      }
      case 'y': {
        opt.background_y = convert_type<int>(optarg);
        break;
      }
      case 'f': {
        opt.background_file = convert_type<std::string>(optarg);
        break;
      }

      /* ------------------------------------------------------- */
      /* visible size */
      case 'a': {
        opt.visible_size = convert_type<float>(optarg);
        break;
      }

      /* ------------------------------------------------------- */
      /* output */
      case 'o': {
        opt.output_file = convert_type<std::string>(optarg);
        break;
      }

      /* ------------------------------------------------------- */
      /* name */
      case 'n': {
        opt.name = convert_type<std::string>(optarg);

        /* we expect that r,g,b has been set */
        if (0 > col_r) {
          printf("Error: you haven't set -r -g -b for the name.\n");
          exit(EXIT_FAILURE);
        }
        opt.name_r = col_r;
        opt.name_g = col_g;
        opt.name_b = col_b;
        break;
      }
      /* name x position */
      case 's': {
        opt.name_x = convert_type<int>(optarg);
        break;
      }
      /* name y position */
      case 't': {
        opt.name_y = convert_type<int>(optarg);
        break;
      }
      /* name font size */
      case 'w': {
        opt.name_font_size = convert_type<float>(optarg);
        break;
      }
      default: {
        printf("Unkown option\n");
        break;
      }
    }
  }
  
  if (false == opt.validate()) {
    printf("+ error: cannot validate the given options.\n");
    exit(EXIT_FAILURE);
  }

  opt.print();

  /* ------------------------------------------------------------------------------------ */

  Image img;
  std::string path;
  std::string ext;
  cairo_surface_t* surf_bg = NULL;
  cairo_format_t img_format = CAIRO_FORMAT_INVALID;

  path = opt.foreground_file;
  if (false == rx_file_exists(path)) {
    printf("+ error: cannot find the file: %s\n", path.c_str());
    exit(EXIT_FAILURE);
  }

  cairo_surface_t* surf_overlay = cairo_image_surface_create_from_png(path.c_str());
  if (NULL == surf_overlay) {
    printf("Error: cannot create s1\n");
    exit(EXIT_FAILURE);
  }

  path = opt.background_file;
  if (false == rx_file_exists(path)) {
    printf("Error: file doesn't exist: %s\n", path.c_str());
    exit(EXIT_FAILURE);
  }
  
  /* check what file type was given. */
  ext = rx_get_file_ext(path);
  if (ext == "jpg") {

    printf("+ warning: jpg as input doesn't seem to work\n");

    /* cairo doesn't have support for PNG? */
    if (0 > rx_load_jpg(path, &img.pixels, img.width, img.height, img.channels)) {
      printf("Error: failed to load: %s\n", path.c_str());
      exit(EXIT_FAILURE);
    }
    if (0 == img.width || 0 == img.height || 0 == img.channels) {
      printf("Error: image has invalid flags: %d x %d, channels: %d\n", img.width, img.height, img.channels);
      exit(EXIT_FAILURE);
    }

    if (3 == img.channels) {
      img_format = CAIRO_FORMAT_RGB24;
      printf("+ Using RGB24\n");
    }  
    else if(4 == img.channels) {
      img_format = CAIRO_FORMAT_ARGB32;
      printf("+ Using ARGB32\n");
    }
    else {
      printf("Error: unsupported number of channels: %d.\n", img.channels);
      exit(EXIT_FAILURE);
    }

    if (NULL != img.pixels && NULL == surf_bg) {

        printf("Stride: %d\n", cairo_format_stride_for_width(img_format, img.width));
        printf("Info: creating %d x %d, channels: %d\n", img.width, img.height, img.channels);

        surf_bg = cairo_image_surface_create_for_data(img.pixels, 
                                                      img_format, 
                                                      img.width, 
                                                      img.height, 
                                                      cairo_format_stride_for_width(img_format, img.width));

#if 0
      /* TESTING */
      cairo_t* cr = cairo_create(surf_bg);
      if (NULL == cr) { 
        printf("Error: cannot create the cairo");
        exit(EXIT_FAILURE);
      }
      path = rx_get_exe_path() +"/generated_polaroid.png";
      cairo_surface_write_to_png(surf_bg, path.c_str());
      printf("Created\n");
      exit(0);
      /* END TESTING */
#endif
    }
  }
  else if (ext == "png") {

    /* use cairo png load feature. */
    surf_bg = cairo_image_surface_create_from_png(path.c_str());
    if (NULL == surf_bg) {
      printf("Error: cannot create s2\n");
      exit(EXIT_FAILURE);
    }

  }
  else {
    printf("Error: unsupported file format: %s\n", ext.c_str());
    exit(EXIT_FAILURE);
  }


  /* make sure the background is loaded correctly (aka the photo) */
  if (NULL == surf_bg) {
    printf("Error: cannot create background surface.\n");
    exit(EXIT_FAILURE);
  }

  if (CAIRO_STATUS_SUCCESS != cairo_surface_status(surf_bg)) {
    printf("Error: something went wrong: %d\n", cairo_surface_status(surf_bg));
    exit(EXIT_FAILURE);
  }

  float source_width = cairo_image_surface_get_width(surf_bg);
  float source_height = cairo_image_surface_get_height(surf_bg);

  /* create output */
  int dest_width = cairo_image_surface_get_width(surf_overlay);
  int dest_height = cairo_image_surface_get_height(surf_overlay);

  if (0 == opt.verbose) {
    printf("+ Output size: %d x %d\n", dest_width, dest_height);
  }

  cairo_surface_t* surf_out = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, dest_width, dest_height);
  if (NULL == surf_out) {
    printf("Error: cannot create cairo_surface_t\n");
    exit(EXIT_FAILURE);
  }

  if (0 == opt.verbose) {
    printf("+ Info: creating output surface: %d x %d\n", dest_width, dest_height);
  }

  cairo_t* cr = cairo_create(surf_out);
  if (NULL == cr) { 
    printf("Error: cannot create the cairo");
    exit(EXIT_FAILURE);
  }

  float scale_factor = opt.visible_size / source_width;
  if (0 == opt.verbose) {
    printf("+ Scale factor: %f\n", scale_factor);
  }

  /* paint background */  
  cairo_save(cr);
  cairo_scale(cr, scale_factor, scale_factor);
  cairo_set_source_surface(cr, surf_bg, opt.background_x, opt.background_y);
  cairo_rectangle(cr, 0, 0, img.width, img.height);
  cairo_paint(cr);
  cairo_restore(cr);

  /* paint overlay */
  cairo_set_source_surface(cr, surf_overlay, 0, 0);
  cairo_paint(cr);
  cairo_surface_flush(surf_out);

  /* font settings. */
  cairo_font_options_t* font_options = cairo_font_options_create();
  if (NULL == font_options) {
    printf("+ Error: cannot create font options. Cannot create polaroid.\n");
    exit(EXIT_FAILURE);
  }
  

  cairo_font_options_set_antialias(font_options, CAIRO_ANTIALIAS_BEST);
  cairo_font_options_set_hint_metrics(font_options, CAIRO_HINT_METRICS_DEFAULT);
  cairo_set_font_options (cr, font_options);
  cairo_select_font_face(cr, "Platform", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
  cairo_set_source_rgba(cr, opt.name_r, opt.name_g, opt.name_b, 1.0); 

  /* name */
  if (0 != opt.name.size()) {
    cairo_move_to(cr, opt.name_x, opt.name_y);
    cairo_set_font_size(cr, opt.name_font_size);
    cairo_show_text(cr, opt.name.c_str());

    cairo_stroke(cr);
    cairo_fill(cr);
  }

  /* hashtag */
  if (0 != opt.hashtag.size()) {
    cairo_select_font_face(cr, "Platform", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
    cairo_move_to(cr, opt.hashtag_x, opt.hashtag_y);
    cairo_set_font_size(cr, opt.name_font_size);
    cairo_show_text(cr, opt.hashtag.c_str());

    cairo_stroke(cr);
    cairo_fill(cr);
  }

  cairo_surface_flush(surf_out);

  /* write out */
  path = opt.output_file;
  cairo_surface_write_to_png(surf_out, path.c_str());

  /* cleanup */
  cairo_surface_destroy(surf_out);
  cairo_surface_destroy(surf_bg);
  cairo_surface_destroy(surf_overlay);
  cairo_destroy(cr);
  
  if (0 == opt.verbose) {
    printf("\n");
  }
  return 0;
}
static cairo_test_status_t
draw (cairo_t *cr, int width, int height)
{
    const cairo_test_context_t *ctx = cairo_test_get_context (cr);
    glyph_array_t glyphs;
    cairo_font_options_t *font_options;
    cairo_status_t status;

    /* paint white so we don't need separate ref images for
     * RGB24 and ARGB32 */
    cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
    cairo_paint (cr);

    cairo_select_font_face (cr, "Bitstream Vera Sans",
			    CAIRO_FONT_SLANT_NORMAL,
			    CAIRO_FONT_WEIGHT_NORMAL);
    cairo_set_font_size (cr, TEXT_SIZE);

    font_options = cairo_font_options_create ();
    cairo_get_font_options (cr, font_options);
    cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_OFF);
    cairo_set_font_options (cr, font_options);
    cairo_font_options_destroy (font_options);

    cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);

    glyph_array_init (&glyphs, 1, TEXT_SIZE);

    status = glyph_array_add_text(&glyphs, cr, "AWAY again", 0.0);
    if (status)
	return cairo_test_status_from_status (ctx, status);

    glyph_array_rel_move_to (&glyphs, TEXT_SIZE*1, 0.0);
    status = glyph_array_add_text(&glyphs, cr, "character space", TEXT_SIZE*0.3);
    if (status)
	return cairo_test_status_from_status (ctx, status);

    glyph_array_show (&glyphs, cr);


    glyph_array_init (&glyphs, 1, TEXT_SIZE*2 + 4);

    status = glyph_array_add_text(&glyphs, cr, "Increasing", 0.0);
    if (status)
	return cairo_test_status_from_status (ctx, status);

    glyph_array_rel_move_to (&glyphs, TEXT_SIZE*0.5, 0.0);
    status = glyph_array_add_text(&glyphs, cr, "space", 0.0);
    if (status)
	return cairo_test_status_from_status (ctx, status);

    glyph_array_rel_move_to (&glyphs, TEXT_SIZE*1.0, 0.0);
    status = glyph_array_add_text(&glyphs, cr, "between", 0.0);
    if (status)
	return cairo_test_status_from_status (ctx, status);

    glyph_array_rel_move_to (&glyphs, TEXT_SIZE*1.5, 0.0);
    status = glyph_array_add_text(&glyphs, cr, "words", 0.0);
    if (status)
	return cairo_test_status_from_status (ctx, status);

    glyph_array_show (&glyphs, cr);

    return CAIRO_TEST_SUCCESS;
}
Exemple #30
0
static void set_cf_antialias(cairo_t *cc) {
	cairo_font_options_t *fo = cairo_font_options_create();
	cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_SUBPIXEL);
	cairo_set_font_options(cc, fo);
	cairo_font_options_destroy(fo);
}