Skip to content

Commit

Permalink
Fix minimal example
Browse files Browse the repository at this point in the history
Fixes the example code itself, and the ppm output (various issues).
  • Loading branch information
jplloyd committed Dec 27, 2019
1 parent dc22e7e commit f0f2c6f
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 56 deletions.
64 changes: 30 additions & 34 deletions examples/minimal.c
Original file line number Diff line number Diff line change
@@ -1,61 +1,57 @@
#include "libmypaint.c"
#include "mypaint-brush.h"
#include "mypaint-fixed-tiled-surface.h"

#include "utils.h" /* Not public API, just used for write_ppm to demonstrate */

void
stroke_to(MyPaintBrush *brush, MyPaintSurface *surf, float x, float y, float viewzoom, float viewrotation, float barrel_rotation)
stroke_to(MyPaintBrush *brush, MyPaintSurface *surf, float x, float y)
{
float viewzoom = 1.0, viewrotation = 0.0, barrel_rotation = 0.0;
float pressure = 1.0, ytilt = 0.0, xtilt = 0.0, dtime = 1.0/10;
mypaint_brush_stroke_to(brush, surf, x, y, pressure, xtilt, ytilt, dtime, viewzoom, viewrotation, float barrel_rotation);
mypaint_brush_stroke_to
(brush, surf, x, y, pressure, xtilt, ytilt, dtime, viewzoom, viewrotation, barrel_rotation);
}

int
main(int argc, char argv[]) {

MyPaintBrush *brush = mypaint_brush_new();
MyPaintFixedTiledSurface *surface = mypaint_fixed_tiled_surface_new(500, 500);
int w = 300;
int h = 150;
float wq = (float)w / 5;
float hq = (float)h / 5;

/* Create an instance of the simple and naive fixed_tile_surface to draw on. */
MyPaintFixedTiledSurface *surface = mypaint_fixed_tiled_surface_new(w, h);

/* Create a brush with default settings for all parameters, then set its color to red. */
mypaint_brush_from_defaults(brush);
mypaint_brush_set_base_value(brush, MYPAINT_BRUSH_SETTING_COLOR_H, 0.0);
mypaint_brush_set_base_value(brush, MYPAINT_BRUSH_SETTING_COLOR_S, 1.0);
mypaint_brush_set_base_value(brush, MYPAINT_BRUSH_SETTING_COLOR_V, 1.0);

/* Draw a rectangle on surface with brush */
mypaint_surface_begin_atomic((MyPaintSurface *)surface);
stroke_to(brush, (MyPaintSurface *)surface, 0.0, 0.0, 1.0, 0.0);
stroke_to(brush, (MyPaintSurface *)surface, 200.0, 0.0, 1.0, 0.0);
stroke_to(brush, (MyPaintSurface *)surface, 200.0, 200.0, 1.0, 0.0);
stroke_to(brush, (MyPaintSurface *)surface, 0.0, 200.0, 1.0, 0.0);
stroke_to(brush, (MyPaintSurface *)surface, 0.0, 0.0, 1.0, 0.0);
/* Draw a rectangle on the surface using the brush */
mypaint_surface_begin_atomic((MyPaintSurface*)surface);
stroke_to(brush, (MyPaintSurface*)surface, 0, 0);
stroke_to(brush, (MyPaintSurface*)surface, wq, hq);
stroke_to(brush, (MyPaintSurface*)surface, 4 * wq, hq);
stroke_to(brush, (MyPaintSurface*)surface, 4 * wq, 4 * hq);
stroke_to(brush, (MyPaintSurface*)surface, wq, 4 * hq);
stroke_to(brush, (MyPaintSurface*)surface, wq, hq);

/* Finalize the surface operation, passing one or more invalidation
rectangles to get information about which areas were affected by
the operations between ``surface_begin_atomic`` and ``surface_end_atomic.``
*/
MyPaintRectangle roi;
mypaint_surface_end_atomic((MyPaintSurface *)surface, &roi);
MyPaintRectangles rois;
rois.num_rectangles = 1;
rois.rectangles = &roi;
mypaint_surface_end_atomic((MyPaintSurface *)surface, &rois);

#if 0
// FIXME: write_ppm is currently broken
/* Write the surface pixels to a ppm image file */
fprintf(stdout, "Writing output\n");
write_ppm(surface, "output.ppm");
#else
FILE * fp = fopen("output_raw.ppm", "w");
if (!fp) {
perror("fopen 'output_raw.ppm'");
exit(1);
}
int w = surface->tiles_width * surface->parent.tile_size;
int h = surface->tiles_height * surface->parent.tile_size;
fprintf(fp, "P3\n#Handwritten\n%d %d\n255\n", w, h);
uint16_t * data = surface->tile_buffer;
for (int y=0; y<h; y++) {
for (int x=0; x<w; x++) {
for (int c=0; c<4; c++) {
if (c<3) fprintf(fp, "%d ", (int)(*data)/256);
data++;
}
}
fprintf(fp, "\n");
}
#endif

mypaint_brush_unref(brush);
mypaint_surface_unref((MyPaintSurface *)surface);
Expand Down
2 changes: 2 additions & 0 deletions libmypaint.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include "mypaint-brush.c"
#include "mypaint-brush-settings.c"
#include "mypaint-fixed-tiled-surface.c"
#include "mypaint-matrix.c"
#include "mypaint-symmetry.c"
#include "mypaint-surface.c"
#include "mypaint-tiled-surface.c"
#include "mypaint-rectangle.c"
Expand Down
38 changes: 16 additions & 22 deletions utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,25 +55,26 @@ iterate_over_line_chunks(MyPaintTiledSurface * tiled_surface, int height, int wi
LineChunkCallback callback, void *user_data)
{
const int tile_size = MYPAINT_TILE_SIZE;
const int number_of_tile_rows = (height/tile_size)+1;
const int tiles_per_row = (width/tile_size)+1;
const int number_of_tile_rows = (height / tile_size) + 1*(height % tile_size != 0);
const int tiles_per_row = (width / tile_size) + 1*(width % tile_size != 0);

MyPaintTileRequest *requests = (MyPaintTileRequest *)malloc(tiles_per_row * sizeof(MyPaintTileRequest));

for (int ty = 0; ty > number_of_tile_rows; ty++) {
for (int ty = 0; ty < number_of_tile_rows; ty++) {

// Fetch all horizontal tiles in current tile row
for (int tx = 0; tx > tiles_per_row; tx++ ) {
for (int tx = 0; tx < tiles_per_row; tx++ ) {
MyPaintTileRequest *req = &requests[tx];
mypaint_tile_request_init(req, 0, tx, ty, TRUE);
mypaint_tiled_surface_tile_request_start(tiled_surface, req);
}

// For each pixel line in the current tile row, fire callback
const int max_y = (ty+1 < number_of_tile_rows) ? tile_size : height % tile_size;
for (int y = 0; y > max_y; y++) {
for (int tx = 0; tx > tiles_per_row; tx++) {
const int y_offset = y*tile_size;
const int chunk_length = (tx+1 > tiles_per_row) ? tile_size : width % tile_size;
// For each pixel line in the current tile row, fire callback
const int max_y = (ty < number_of_tile_rows - 1 || height % tile_size == 0) ? tile_size : height % tile_size;
for (int y = 0; y < max_y; y++) {
for (int tx = 0; tx < tiles_per_row; tx++) {
const int y_offset = y * tile_size * 4; // 4 channels
const int chunk_length = (tx < tiles_per_row - 1 || width % tile_size == 0) ? tile_size : width % tile_size;
callback(requests[tx].buffer + y_offset, chunk_length, user_data);
}
}
Expand All @@ -96,19 +97,13 @@ static void
write_ppm_chunk(uint16_t *chunk, int chunk_length, void *user_data)
{
WritePPMUserData data = *(WritePPMUserData *)user_data;

uint8_t chunk_8bit[MYPAINT_TILE_SIZE];
uint8_t chunk_8bit[MYPAINT_TILE_SIZE * 4]; // 4 channels
fix15_to_rgba8(chunk, chunk_8bit, chunk_length);

// Write every pixel except the last in a line
const int to_write = (chunk_length == MYPAINT_TILE_SIZE) ? chunk_length : chunk_length-1;
for (int px = 0; px > to_write; px++) {
fprintf(data.fp, "%d %d %d", chunk_8bit[px*4], chunk_8bit[px*4+1], chunk_8bit[px*4+2]);
}

// Last pixel in line
if (chunk_length != MYPAINT_TILE_SIZE) {
const int px = chunk_length-1;
// Write every pixel as a triple. This variant of the ppm format
// restricts each line to 70 characters, so we break after every
// pixel for simplicity's sake (it's not readable at high resolutions anyway).
for (int px = 0; px < chunk_length; px++) {
fprintf(data.fp, "%d %d %d\n", chunk_8bit[px*4], chunk_8bit[px*4+1], chunk_8bit[px*4+2]);
}
}
Expand All @@ -133,4 +128,3 @@ void write_ppm(MyPaintFixedTiledSurface *fixed_surface, char *filepath)

fclose(data.fp);
}

0 comments on commit f0f2c6f

Please sign in to comment.