Graph Tools Cairo Draw Seg Fault
This instructor is derivative from Michael Urman's El Qahira teacher for python programmers. The original code snippets have been translated to C, the text has only if been changed as a great deal every bit necessary.
Cairo is a powerful 2d graphics library. This document introduces you to how cairo works and umteen of the functions you volition wont to create the graphic experience you desire.
Systematic to abide by along on your computer, you require the following things:
-
Cairo itself. You will need some the program library and the evolution files. See Download if you don't have it already.
-
A C compiler. The FAQ contains a minimal model on how to turn the code into a program that produces the wanted turnout.
If you desire to see the code snippets included in this tutorial in action mechanism, you can try to click connected some of the images. You will get a pocket-sized C program which includes the represented drawing code.
Alternately, if you're up for a challenge, you can transform the examples to your preferred language and host environment and only need cairo from above.
Note: The text mentions
cairo_push_group()andcairo_pop_group(). At least cairo version 1.2.0 is needful for this.
Table of Contents
- El Qahira's Draft Model
- Nouns
- Verbs
- Drawing with Al Qahira
- Preparing and Selecting a Source
- Creating a Path
- Understanding Text
- Working with Transforms
- Where to Go Next
- Tips and Tricks
- Strain Breadth
- Text Conjunction
Capital of Egypt's Drawing Model
In arrange to explain the operations used by cairo, we first dig into a model of how cairo models drawing. There are lonesome a few concepts interested, which are then applied over and over by the different methods. First gear I'll describe the nouns: destination, source, mask, route, and context. After that I'll describe the verbs which offer ways to manipulate the nouns and draw the nontextual matter you wish to create.
Nouns
Cairo's nouns are somewhat abstract. To make them concrete I'm including diagrams that depict how they interact. The first ternion nouns are the ternary layers in the diagrams you see in this section. The fourth noun, the path, is drawn on the middle stratum when information technology is relevant. The ultimate noun, the context, isn't shown.
Name and address
The destination is the surface on which you're drawing. It may be tied to an array of pixels like in this tutorial, OR it might be level to a SVG operating theatre PDF file away, or something else. This surface collects the elements of your graphic as you apply them, allowing you to fortify a complex work as though house painting on a canvas.
Source
The source is the "paint" you're about to work with. I show this as it is—plain black for some examples—but translucent to show lower layers. Unlike real paint, it doesn't have to be a single color; it can be a pattern operating room even a antecedently created destination surface (get word How do I blusher from one surface to some other?). Too unlike tangible key it can contain transparency information—the Alpha channel.
Mask
The mask is the all but chief opus: IT controls where you give the rootage to the destination. I will show it as a yellow stratum with holes where it lets the source through. When you go for a drawing verb, it's wish you stamp the reference to the destination. Anywhere the mask allows, the reservoir is copied. Anywhere the cloak disallows, nothing happens.
Path
The way of life is somewhere between function of the dissemble and part of the context. I leave show it as thin green lines on the mask layer. Information technology is manipulated by path verbs, then secondhand by drawing verbs.
Context
The context of use keeps track of everything that verbs dissemble. It tracks one source, one terminus, and one mask. It also tracks several helper variables like your line breadth and style, your font face and size of it, and more. Most importantly it tracks the path, which is turned into a mask by draught verbs.
Before you can start to draw something with cairo, you need to create the context. The linguistic context is stored in cairo's telephone exchange data type, called cairo_t. When you produce a cairo context, IT must be level to a specific surface—for example, an image airfoil if you require to create a PNG data file. There is also a data type for the surface, called cairo_surface_t. You can initialize your cairo context like this:
cairo_surface_t *surface; cairo_t *cr; grade-constructed = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 120, 120); cr = cairo_create (surface); The cairo context of use therein exercise is tied to an image coat of dimension 120 x 120 and 32 bits per pixel to store RGB and Alpha information. Surfaces fanny personify created specific to just about cairo backends, take in the manual of arms for details.
Verbs
The grounds you are victimisation cairo in a program is to draw. Cairo internally draws with unmatchable fundamental draftsmanship operation: the source and mask are freely placed somewhere over the terminus. So the layers are altogether ironed together and the paint from the source is transferred to the destination wherever the dissemble allows IT. So far the following five drawing verbs, Oregon operations, are all similar. They disagree by how they retrace the mask.
Stroke
The cairo_stroke() operation takes a virtual write out along the course. It allows the source to transfer through the dissemble in a thin (or chummy) line or so the path, according to the pen's crinkle breadth, dash style, and line caps.
Note: To see the codification snippet in legal action, use the stroke.c file linked from the figure to the right. Just pasting the snippet into the FAQ's hello.c might give unexpected results due to antithetic grading. Record on; grading is explained in department Working with Transforms at a lower place.
cairo_set_line_width (chromium, 0.1); cairo_set_source_rgb (cr, 0, 0, 0); cairo_rectangle (cr, 0.25, 0.25, 0.5, 0.5); cairo_stroke (cr); Take
The cairo_fill() operation rather uses the path like the lines of a coloring book, and allows the source through the mask inside the hole whose boundaries are the track. For complex paths (paths with multiple closed sub-paths—like a doughnut—OR paths that individual-intersect) this is influenced by the take linguistic rule. Note that while stroke the path transfers the source for half of the subscriber line width along each side of the path, filling a path fills directly up to the edge of the path and no further.
cairo_set_source_rgb (cr, 0, 0, 0); cairo_rectangle (chromium, 0.25, 0.25, 0.5, 0.5); cairo_fill (cr); Show Text / Glyphs
The cairo_show_text() operation forms the mask from text. It May follow easier to think of cairo_show_text() As a shortcut for creating a path with cairo_text_path() and then using cairo_fill() to transfer IT. Be aware cairo_show_text() caches glyphs so is much more efficient if you work with much of text.
cairo_text_extents_t atomic number 52; cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); cairo_select_font_face (chromium, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size (cr, 1.2); cairo_text_extents (cr, "a", &te); cairo_move_to (cr, 0.5 - te.breadth / 2 - tellurium.x_bearing, 0.5 - te.height / 2 - si.y_bearing); cairo_show_text (Cr, "a"); Paint
The cairo_paint() surgery uses a masquerade party that transfers the entire beginning to the goal. Some multitude reckon this an infinitely large mask, and others view information technology no mask; the result is the same. The related operation cairo_paint_with_alpha() similarly allows transfer of the full source to destination, but it transfers only the provided portion of the color.
cairo_set_source_rgb (Cr, 0.0, 0.0, 0.0); cairo_paint_with_alpha (cr, 0.5); Mask
The cairo_mask() and cairo_mask_surface() operations allow transfer according to the transparentness/opacity of a second reference pattern or surface. Where the pattern or surface is opaque, the current source is transferred to the address. Where the pattern or surface is square, nada is transferred.
cairo_pattern_t *linpat, *radpat; linpat = cairo_pattern_create_linear (0, 0, 1, 1); cairo_pattern_add_color_stop_rgb (linpat, 0, 0, 0.3, 0.8); cairo_pattern_add_color_stop_rgb (linpat, 1, 0, 0.8, 0.3); radpat = cairo_pattern_create_radial (0.5, 0.5, 0.25, 0.5, 0.5, 0.75); cairo_pattern_add_color_stop_rgba (radpat, 0, 0, 0, 0, 1); cairo_pattern_add_color_stop_rgba (radpat, 0.5, 0, 0, 0, 0); cairo_set_source (cr, linpat); cairo_mask (cr, radpat); Drawing with Cairo
In order to make up an image you desire, you have to prepare the context for each of the drawing verbs. To use cairo_stroke() operating room cairo_fill() you first penury a way. To use cairo_show_text() you essential perspective your text by its insertion point. To use cairo_mask() you take a second source pattern or shallow. And to exercise any of the operations, including cairo_paint(), you need a primary seed.
Preparing and Selecting a Generator
In that location are three main kinds of sources in cairo: colors, gradients, and images. Colors are the simplest; they use a dedifferentiated hue and opaqueness for the entire germ. You can select these without whatsoever preparation with cairo_set_source_rgb() and cairo_set_source_rgba(). Using cairo_set_source_rgb (chromium, r, g, b) is equivalent to using cairo_set_source_rgba (atomic number 24, r, g, b, 1.0), and it sets your seed vividness to purpose full opacity.
cairo_set_source_rgb (chromium, 0, 0, 0); cairo_move_to (cr, 0, 0); cairo_line_to (cr, 1, 1); cairo_move_to (Cr, 1, 0); cairo_line_to (cr, 0, 1); cairo_set_line_width (cr, 0.2); cairo_stroke (Cr); cairo_rectangle (cr, 0, 0, 0.5, 0.5); cairo_set_source_rgba (cr, 1, 0, 0, 0.80); cairo_fill (cr); cairo_rectangle (atomic number 24, 0, 0.5, 0.5, 0.5); cairo_set_source_rgba (cr, 0, 1, 0, 0.60); cairo_fill (cr); cairo_rectangle (cr, 0.5, 0, 0.5, 0.5); cairo_set_source_rgba (Cr, 0, 0, 1, 0.40); cairo_fill (Cr); Gradients discover a progression of colours by setting a startle and kibosh cite location and a serial publication of "stops" along the room. Linear gradients are built from two points which pass through antiparallel lines to delimit the start and plosive speech sound locations. Radial-ply tire gradients are also built from two points, but each has an connected radius of the circle on which to define the start and stop locations. Stops are added to the gradient with cairo_add_color_stop_rgb() and cairo_add_color_stop_rgba() which take a colorize like cairo_set_source_rgb*(), American Samoa well every bit an offset to betoken where it lies between the reference locations. The colors between adjacent Chicago are averaged finished space to var. a smooth blend. Finally, the behavior on the far side the reference locations ass be pressurized with cairo_set_extend().
int i, j; cairo_pattern_t *radpat, *linpat; radpat = cairo_pattern_create_radial (0.25, 0.25, 0.1, 0.5, 0.5, 0.5); cairo_pattern_add_color_stop_rgb (radpat, 0, 1.0, 0.8, 0.8); cairo_pattern_add_color_stop_rgb (radpat, 1, 0.9, 0.0, 0.0); for (i=1; i<10; i++) for (j=1; j<10; j++) cairo_rectangle (cr, i/10.0 - 0.04, j/10.0 - 0.04, 0.08, 0.08); cairo_set_source (Cr, radpat); cairo_fill (Cr); linpat = cairo_pattern_create_linear (0.25, 0.35, 0.75, 0.65); cairo_pattern_add_color_stop_rgba (linpat, 0.00, 1, 1, 1, 0); cairo_pattern_add_color_stop_rgba (linpat, 0.25, 0, 1, 0, 0.5); cairo_pattern_add_color_stop_rgba (linpat, 0.50, 1, 1, 1, 0); cairo_pattern_add_color_stop_rgba (linpat, 0.75, 0, 0, 1, 0.5); cairo_pattern_add_color_stop_rgba (linpat, 1.00, 1, 1, 1, 0); cairo_rectangle (atomic number 24, 0.0, 0.0, 1, 1); cairo_set_source (cr, linpat); cairo_fill (cr); Images admit both surfaces loaded from existing files with cairo_image_surface_create_from_png() and surfaces created from within cairo atomic number 3 an to begin with destination. As of cairo 1.2, the easiest path to make and use an earlier destination atomic number 3 a source is with cairo_push_group() and either cairo_pop_group() surgery cairo_pop_group_to_source(). Use cairo_pop_group_to_source() to use it honorable until you select a fres source, and cairo_pop_group() when you want to keep open it so you can select IT again and again with cairo_set_source().
Creating a Path
Capital of Egypt always has an nimble path. If you call cairo_stroke() it leave draw the path with your line settings. If you call cairo_fill() it will fill the inside of the path. But as often as not, the path is empty-bellied, and some calls leave result in no change to your address. Why is it empty so often? For one, IT starts that way; but more than importantly subsequently for each one cairo_stroke() or cairo_fill() it is emptied again to let you start building your next path.
What if you require to do multiple things with the unvaried path? For instance to pull in a reddened rectangle with a blackened border, you would want to fill in the rectangle path with a red source, and then fondle the same route with a black source. A rectangle path is easy to create multiple times, but a great deal of paths are more complex.
Cairo supports easily reusing paths by having alternate versions of its operations. Both draw the same thing, but the alternate doesn't readjust the path. For stroking, aboard cairo_stroke() there is cairo_stroke_preserve(); for filling, cairo_fill_preserve() joins cairo_fill(). Even setting the clip has a carry on variant. Apart from choosing when to preserve your path, at that place are only a couple common operations.
Moving
Egyptian capital uses a connect-the-dots style scheme when creating paths. Start at 1, draw a line to 2, then 3, etcetera. When you start a path, or when you need to start a recent sub-path, you wish it to be like point 1: information technology has nothing copulative thereto. For this, use cairo_move_to(). This sets the current reference point without making the path connect the preceding place to it. Thither is also a relative coordinate variant, cairo_rel_move_to(), which sets the other reference work a specified distance away from the current quotation or else. After setting your first reference point, use the other path operations which both update the reference point point and connect to it in some manner.
cairo_move_to (chromium, 0.25, 0.25); Straight Lines
Whether with absolute coordinates cairo_line_to() (extend the itinerary from the reference to this stage), or relative coordinates cairo_rel_line_to() (extend the path from the reference this off the beaten track in that direction), the course connection testament be a correct line. The new reference item wish be at the other remainder of the line.
cairo_line_to (cr, 0.5, 0.375); cairo_rel_line_to (cr, 0.25, -0.125); Arcs
Arcs are parts of the outside of a lot. Unlike straight lines, the tip you directly pin down is not on the course. Instead it is the shopping center of the circle that makes up the addition to the path. Some a starting and ending detail on the roach must be specific, and these points are connected either clockwise by cairo_arc() or counter-clockwise by cairo_arc_negative(). If the previous reference gunpoint is non on this new swerve, a unbent line is added from it to where the arc begins. The acknowledgment point is then updated to where the arc ends. There are only absolute versions.
cairo_arc (chromium, 0.5, 0.5, 0.25 * sqrt(2), -0.25 * M_PI, 0.25 * M_PI); Curves
Curves in Cairo are cubic Bézier splines. They start at the current point of reference and swimmingly follow the direction of deuce other points (without going through and through them) to get to a third specified point. Wish lines, in that location are some absolute (cairo_curve_to()) and relative (cairo_rel_curve_to()) versions. Note that the relative variant specifies wholly points relative to the previous reference point, rather than each relative to the preceding mastery point of the curve.
cairo_rel_curve_to (chromium, -0.25, -0.125, -0.25, 0.125, -0.5, 0); Close the path
Cairo can also close the route by drawing a straight line to the beginning of the current sub-path. This straight bank line can be useful for the last edge of a polygon, just is non directly profitable for curve-based shapes. A closed path is basically different from an open path: it's extraordinary nonstop path and has nobelium start or end. A closed path has no line of reasoning caps for there is no place to put them.
cairo_close_path (cr); Text
Finally textual matter rump be sour into a path with cairo_text_path(). Paths created from text are like any other path, supporting stroke or fill operations. This path is placed anchored to the current point of reference, so cairo_move_to() your desired location before turn text into a path. However in that respect are execution concerns to doing this if you are running with a lot of text; when manageable you should prefer using the verb cairo_show_text() terminated cairo_text_path() and cairo_fill().
Understanding Text
To use text effectively you indigence to know where IT will go. The methods cairo_font_extents() and cairo_text_extents() get you this info. Since this diagram is serious to see then small, I suggest getting its source and relegate the scrutinise to 600. It shows the relation between the reference (red dot); advisable next point of reference (blue Transportation); bounding box (dashed blue lines); bearing displacement (solid blue line); and height, ascent, baseline, and descent lines (dashed fleeceable).
The reference point is ever on the baseline. The descent line is infra that, and reflects a rough bounding box for all characters in the font. However it is an artistic choice intended to indicate coalition rather than a true bounding box. The same is true for the ascent trace above. Next higher up that is the height line, the artist-recommended spatial arrangement between ensuant baselines. All cardinal of these are reported arsenic distances from the baseline, and expected to be positive despite their differing directions.
The bearing is the supplanting from the reference maneuver to the upper-left corner of the bounding box. It is often nada or a small positive assess for x displacement, but can atomic number 4 negative x for characters like j as shown; it's almost always a negative value for y displacement. The width and stature then report the size up of the bounding box. The advance takes you to the suggested reference for the next letter. Federal Reserve note that bounding boxes for subsequent blocks of textbook can overlap if the bearing is negative, or the advance is smaller than the width would indicate.
In addition to placement, you also need to specify a face, style, and sized. Set the face and style together with cairo_select_font_face(), and the size with cairo_set_font_size(). If you deman symmetric finer control, strain getting a cairo_font_options_t with cairo_get_font_options(), tweaking IT, and scope it with cairo_set_font_options().
Working with Transforms
Transforms have three major uses. First they allow for you to piece a coordinate system that's easy to think in and work in, yet have the output be of any size of it. Second they countenance you to shuffle helper functions that work at or around a (0, 0) but can be applied anyplace in the output image. Third they have you deform the image, turning a cumuliform arc into an elliptic arc, etc. Transforms are a direction of setting up a relation between two coordinate systems. The device-space coordinate arrangement is united to the surface, and cannot change. The user-space frame of reference matches that space by default, but can be changed for the above reasons. The helper functions cairo_user_to_device() and cairo_user_to_device_distance() tell you what the twist-coordinates are for a drug user-coordinates position or distance. Correspondingly cairo_device_to_user() and cairo_device_to_user_distance() tell you user-coordinates for a device-coordinates position or distance. Remember to place positions through the non-distance variant, and relative moves or other distances through the distance variant.
I leverage all of these reasons to draw the diagrams in this papers. Whether I'm drawing 120 x 120 or 600 x 600, I use cairo_scale() to give ME a 1.0 x 1.0 workspace. To place the results on the right column, so much arsenic in the give-and-take of cairo's drawing off model, I use cairo_translate(). And to add the view view for the overlapping layers, I set up an arbitrary deformation with cairo_transform() connected a cairo_matrix_t.
To realise your transforms, read them bottommost to top side, applying them to the point you'Ra drawing. To figure out which transforms to make up, think through this operation in reverse. E.g. if I want my 1.0 x 1.0 workspace to Be 100 x 100 pixels in the middle of a 120 x 120 pel surface, I can buoy set it up one of tierce slipway:
-
cairo_translate (cr, 10, 10); cairo_scale (chromium, 100, 100); -
cairo_scale (cr, 100, 100); cairo_translate (cr, 0.1, 0.1); -
cairo_matrix_t tangle; cairo_matrix_init (&mat up, 100, 0, 0, 100, 10, 10); cairo_transform (cr, &mat);
Use the first when in dispute because it is oftentimes the most decipherable; use the 3rd when requisite to access additive control not available with the primary functions.
Be careful when disagreeable to draw lines patc under transform. Even if you set your line width while the shell factor was 1, the line breadth background is e'er in user-coordinates and isn't modified by setting the scale. While you'atomic number 75 operating under a surmount, the width of your line is increased by that scale. To specify a breadth of a stemma in pixels, use cairo_device_to_user_distance() to release a (1, 1) device-space distance into, e.g., a (0.01, 0.01) user-place outstrip. Note that if your transform deforms the image there isn't inevitably a way to delimitate a line with a uniform width.
Where to Move Next
This wraps up the teacher. IT doesn't cover totally functions in Egyptian capital, so for some "advanced" lesser-used features, you'll motivation to look elsewhere. The write in code behind the examples (layer diagrams, drawing illustrations) uses a handful of techniques that aren't described within, so analyzing them English hawthorn be a good freshman stair. Other examples on cairographics.org result in incompatible directions. Arsenic with everything, there's a conspicuous gap between knowing the rules of the tool, and being able to use it well. The final section of this document provides some ideas to help you traverse parts of the gap.
Tips and Tricks
In the previous sections you should have built up a truehearted savvy of the operations cairo uses to create images. In this division I've put together a small handful of snippets I've found particularly useful or non-obvious. I'm still new to cairo myself, so at that place may be new advisable slipway to do these things. If you see a better way, Oregon find a cool manner to do something else, let me have sex and perhaps I can incorporate it into these tips.
Seam Width
When you're functional under a uniform grading transmute, you can't sporty use pixels for the width of your line. However it's soft to translate it with the help of cairo_device_to_user_distance() (assuming that the pixel breadth is 1):
double uxor=1, uy=1; cairo_device_to_user_distance (cr, &ux, &uy); if (ux < uy) ux = uy; cairo_set_line_width (cr, ux); When you're working under a deforming scale, you may wish to still have line widths that are consistent in twist space. For this you should return to a uniform scale ahead you cerebrovascular accident the path. In the image, the arc on the left is stroked under a deformation, piece the arc on the right is stroked low-level a uniform scurf.
cairo_set_line_width (atomic number 24, 0.1); cairo_save (chromium); cairo_scale (Cr, 0.5, 1); cairo_arc (cr, 0.5, 0.5, 0.40, 0, 2 * M_PI); cairo_stroke (atomic number 24); cairo_translate (cr, 1, 0); cairo_arc (cr, 0.5, 0.5, 0.40, 0, 2 * M_PI); cairo_restore (cr); cairo_stroke (cr); Text Alliance
When you try to center text letter by letter at various locations, you have to decide how you want to center information technology. E.g. the tailing code will in reality center letters individually, leading to bust results when your letters are of different sizes. (Different most examples, present I assume a 26 x 1 workspace.)
cairo_text_extents_t te; char alphabet[] = "AbCdEfGhIjKlMnOpQrStUvWxYz"; char alphabetic character[2]; for (i=0; i < strlen(alphabet); i++) { *letter = '\0'; strncat (letter, alphabet + i, 1); cairo_text_extents (atomic number 24, letter, &ti); cairo_move_to (chromium, i + 0.5 - te.x_bearing - tellurium.width / 2, 0.5 - te.y_bearing - te.to / 2); cairo_show_text (cr, letter); } Or else the semi-climbing centering moldiness be supported the general size of the font, so keeping your baseline steady. Note that the exact placement now depends on the metrics provided by the baptismal font itself, so the results are not necessarily the same from font to font.
cairo_font_extents_t fe; cairo_text_extents_t te; char alphabet[] = "AbCdEfGhIjKlMnOpQrStUvWxYz"; char letter[2]; cairo_font_extents (cr, &A;fe); for (i=0; i < strlen(first principle); i++) { *letter of the alphabet = '\0'; strncat (varsity letter, alphabet + i, 1); cairo_text_extents (cr, varsity letter, &A;te); cairo_move_to (atomic number 24, i + 0.5 - te.x_bearing - te.breadth / 2, 0.5 - fe.descent + fe.height / 2); cairo_show_text (cr, missive); } Right of first publication © 2005–2007 Michael Urman
Graph Tools Cairo Draw Seg Fault
Source: https://www.cairographics.org/tutorial/
0 Response to "Graph Tools Cairo Draw Seg Fault"
Post a Comment