Skip to content

Commit

Permalink
gral_draw_context_add_text
Browse files Browse the repository at this point in the history
  • Loading branch information
eyelash committed Nov 6, 2024
1 parent de40885 commit ab8e894
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 13 deletions.
70 changes: 57 additions & 13 deletions demos/draw.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,17 @@

#define RAD(deg) ((deg) * ((float)M_PI / 180.0f))

#define FONT_SIZE 80.0f

struct demo_application {
struct gral_application *application;
};

struct demo_window {
struct gral_window *window;
struct gral_text *text;
float ascent;
float descent;
};

static void destroy(void *user_data) {
Expand Down Expand Up @@ -81,22 +86,57 @@ static void add_star(struct gral_draw_context *draw_context, float x, float y, f
gral_draw_context_close_path(draw_context);
}

static void draw(struct gral_draw_context *draw_context, int x, int y, int width, int height, void *user_data) {
add_rectangle(draw_context, 20.0f, 20.0f, 160.0f, 160.0f);
gral_draw_context_fill(draw_context, 0.9f, 0.1f, 0.1f, 1.0f);
add_rectangle(draw_context, 220.0f, 20.0f, 160.0f, 160.0f);
gral_draw_context_stroke(draw_context, 4.0f, 0.1f, 0.1f, 0.9f, 1.0f);
add_rectangle(draw_context, 420.0f, 20.0f, 160.0f, 160.0f);
struct gral_gradient_stop stops[] = {
{0.0f, 0.9f, 0.1f, 0.1f, 1.0f},
{0.3f, 0.9f, 0.9f, 0.1f, 1.0f},
{1.0f, 0.1f, 0.9f, 0.1f, 1.0f}
};
gral_draw_context_fill_linear_gradient(draw_context, 420.0f, 20.0f, 580.0f, 100.0f, stops, 3);
static void add_shapes(struct gral_draw_context *draw_context) {
add_circle(draw_context, 20.0f, 220.0f, 160.0f);
add_rounded_rectangle(draw_context, 220.0f, 220.0f, 160.0f, 160.0f, 20.0f);
add_star(draw_context, 420.0f, 220.0f, 160.0f);
gral_draw_context_fill(draw_context, 0.1f, 0.1f, 0.9f, 1.0f);
}

static void draw(struct gral_draw_context *draw_context, int x, int y, int width, int height, void *user_data) {
struct demo_window *window = user_data;
float text_width = gral_text_get_width(window->text, draw_context);
float text_height = window->ascent + window->descent;
float text_x = (600.0f - text_width) / 2.0f;
float text_y = (200.0f - text_height) / 2.0f + window->ascent;

// background
add_rectangle(draw_context, 0.0f, 0.0f, width, height);
gral_draw_context_fill(draw_context, 0.2f, 0.2f, 0.2f, 1.0f);

// grid
add_rectangle(draw_context, 0.0f, roundf(text_y), 600.0f, 1.0f);
add_rectangle(draw_context, 0.0f, roundf(text_y - window->ascent), 600.0f, 1.0f);
add_rectangle(draw_context, 0.0f, roundf(text_y + window->descent), 600.0f, 1.0f);
int i;
for (i = 0; i <= 7; i++) {
float x = gral_text_index_to_x(window->text, i);
add_rectangle(draw_context, roundf(text_x + x), 0.f, 1.0f, 200.0f);
}
static struct gral_gradient_stop const grid_stops[] = {
{0.0f, 0.4f, 0.4f, 0.4f, 1.0f},
{1.0f, 0.2f, 0.2f, 0.2f, 1.0f}
};
gral_draw_context_fill_linear_gradient(draw_context, 0.0f, 0.0f, 0.0f, 200.0f, grid_stops, 2);

// text and shapes
gral_draw_context_add_text(draw_context, window->text, roundf(text_x), roundf(text_y));
add_shapes(draw_context);
static struct gral_gradient_stop const fill_stops[] = {
{0.00f, 0.7f, 0.7f, 0.0f, 1.0f}, // yellow
{0.35f, 0.7f, 0.4f, 0.0f, 1.0f}, // orange
{0.65f, 0.7f, 0.0f, 0.0f, 1.0f}, // red
{1.00f, 0.7f, 0.0f, 0.4f, 1.0f} // purple
};
gral_draw_context_fill_linear_gradient(draw_context, 20.0f, 0.0f, 580.0f, 0.0f, fill_stops, 4);
gral_draw_context_add_text(draw_context, window->text, roundf(text_x), roundf(text_y));
add_shapes(draw_context);
static struct gral_gradient_stop const stroke_stops[] = {
{0.00f, 1.0f, 1.0f, 0.0f, 1.0f}, // yellow
{0.35f, 1.0f, 0.5f, 0.0f, 1.0f}, // orange
{0.65f, 1.0f, 0.0f, 0.0f, 1.0f}, // red
{1.00f, 1.0f, 0.0f, 0.5f, 1.0f} // purple
};
gral_draw_context_stroke_linear_gradient(draw_context, 2.0f, 20.0f, 0.0f, 580.0f, 0.0f, stroke_stops, 4);
}

static void resize(int width, int height, void *user_data) {
Expand Down Expand Up @@ -178,6 +218,10 @@ static void create_window(void *user_data) {
&focus_leave
};
window->window = gral_window_create(application->application, 600, 400, "gral draw demo", &window_interface, window);
struct gral_font *font = gral_font_create_default(window->window, FONT_SIZE);
window->text = gral_text_create(window->window, "libgral", font);
gral_font_get_metrics(window->window, font, &window->ascent, &window->descent);
gral_font_delete(font);
gral_window_set_minimum_size(window->window, 600, 400);
gral_window_show(window->window);
}
Expand Down
1 change: 1 addition & 0 deletions gral.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ int gral_text_x_to_index(struct gral_text *text, float x);

void gral_draw_context_draw_image(struct gral_draw_context *draw_context, struct gral_image *image, float x, float y);
void gral_draw_context_draw_text(struct gral_draw_context *draw_context, struct gral_text *text, float x, float y, float red, float green, float blue, float alpha);
void gral_draw_context_add_text(struct gral_draw_context *draw_context, struct gral_text *text, float x, float y);
void gral_draw_context_close_path(struct gral_draw_context *draw_context);
void gral_draw_context_move_to(struct gral_draw_context *draw_context, float x, float y);
void gral_draw_context_line_to(struct gral_draw_context *draw_context, float x, float y);
Expand Down
6 changes: 6 additions & 0 deletions gral_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,12 @@ void gral_draw_context_draw_text(struct gral_draw_context *draw_context, struct
pango_cairo_show_layout_line((cairo_t *)draw_context, line);
}

void gral_draw_context_add_text(struct gral_draw_context *draw_context, struct gral_text *text, float x, float y) {
cairo_move_to((cairo_t *)draw_context, x, y);
PangoLayoutLine *line = pango_layout_get_line_readonly(PANGO_LAYOUT(text), 0);
pango_cairo_layout_line_path((cairo_t *)draw_context, line);
}

void gral_draw_context_close_path(struct gral_draw_context *draw_context) {
cairo_close_path((cairo_t *)draw_context);
}
Expand Down
24 changes: 24 additions & 0 deletions gral_macos.m
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,30 @@ void gral_draw_context_draw_text(struct gral_draw_context *draw_context, struct
CFRelease(line);
}

void gral_draw_context_add_text(struct gral_draw_context *draw_context, struct gral_text *text, float x, float y) {
CTLineRef line = CTLineCreateWithAttributedString((CFAttributedStringRef)text);
CGContextTranslateCTM((CGContextRef)draw_context, x, y);
CGContextSetTextMatrix((CGContextRef)draw_context, CGAffineTransformMakeScale(1.0f, -1.0f));
CFArrayRef glyphRuns = CTLineGetGlyphRuns(line);
for (int i = 0; i < CFArrayGetCount(glyphRuns); i++) {
CTRunRef run = CFArrayGetValueAtIndex(glyphRuns, i);
CGPoint const *positions = CTRunGetPositionsPtr(run);
CGGlyph const *glyphs = CTRunGetGlyphsPtr(run);
int count = CTRunGetGlyphCount(run);
CFDictionaryRef attributes = CTRunGetAttributes(run);
CTFontRef font = CFDictionaryGetValue(attributes, kCTFontAttributeName);
for (int j = 0; j < count; j++) {
CGContextSetTextPosition((CGContextRef)draw_context, positions[j].x, positions[j].y);
CGAffineTransform matrix = CGContextGetTextMatrix((CGContextRef)draw_context);
CGPathRef path = CTFontCreatePathForGlyph(font, glyphs[j], &matrix);
CGContextAddPath((CGContextRef)draw_context, path);
CGPathRelease(path);
}
}
CGContextTranslateCTM((CGContextRef)draw_context, -x, -y);
CFRelease(line);
}

void gral_draw_context_close_path(struct gral_draw_context *draw_context) {
CGContextClosePath((CGContextRef)draw_context);
}
Expand Down
4 changes: 4 additions & 0 deletions gral_windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -797,6 +797,10 @@ void gral_draw_context_draw_text(gral_draw_context *draw_context, gral_text *tex
text->layout->Draw(draw_context, renderer, x, y-line_metrics.baseline);
}

void gral_draw_context_add_text(gral_draw_context *draw_context, gral_text *text, float x, float y) {
// TODO: implement
}

void gral_draw_context_close_path(gral_draw_context *draw_context) {
draw_context->sink->EndFigure(D2D1_FIGURE_END_CLOSED);
draw_context->open = false;
Expand Down

0 comments on commit ab8e894

Please sign in to comment.