mirror of
https://github.com/google/pebble.git
synced 2025-03-24 04:29:07 +00:00
847 lines
33 KiB
C
847 lines
33 KiB
C
/*
|
|
* Copyright 2024 Google LLC
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "applib/graphics/gtypes.h"
|
|
#include "applib/graphics/graphics.h"
|
|
#include "util/attributes.h"
|
|
|
|
#include "clar.h"
|
|
#include "util.h"
|
|
|
|
|
|
// Helper Functions
|
|
////////////////////////////////////
|
|
#include "test_graphics.h"
|
|
#include "${BIT_DEPTH_NAME}/test_framebuffer.h"
|
|
|
|
// Stubs
|
|
////////////////////////////////////
|
|
#include "graphics_common_stubs.h"
|
|
#include "stubs_applib_resource.h"
|
|
|
|
// Definitions
|
|
#define SW_EVEN 4
|
|
#define SW_ODD 5
|
|
|
|
// Includes all possible fields for all shapes
|
|
// The fields that are not needed for a particular shape will be zeroed out.
|
|
typedef struct PACKED {
|
|
char func[30];
|
|
GContext ctx;
|
|
GPoint p0;
|
|
GPoint p1;
|
|
GRect r0;
|
|
uint16_t radius;
|
|
uint8_t quadrant;
|
|
GCornerMask corner_mask;
|
|
int16_t major_axis_offset;
|
|
Fixed_S16_3 offset_start;
|
|
Fixed_S16_3 offset_stop;
|
|
bool anti_aliased;
|
|
uint16_t brightness;
|
|
GColor color;
|
|
GBitmap fb;
|
|
} ArgsForMock;
|
|
|
|
static ArgsForMock s_last_args_for_mock;
|
|
static GContext context;
|
|
static FrameBuffer *fb = NULL;
|
|
|
|
/////////////////////////////////////
|
|
/// FUNCTION OVERRIDES
|
|
/////////////////////////////////////
|
|
void graphics_line_draw_1px_non_aa(GContext* ctx, GPoint p0, GPoint p1) {
|
|
s_last_args_for_mock = (ArgsForMock){
|
|
.ctx = *ctx,
|
|
.p0 = p0,
|
|
.p1 = p1
|
|
};
|
|
strncpy(s_last_args_for_mock.func, __func__, sizeof(s_last_args_for_mock.func));
|
|
}
|
|
|
|
void graphics_line_draw_1px_aa(GContext* ctx, GPoint p0, GPoint p1) {
|
|
s_last_args_for_mock = (ArgsForMock){
|
|
.ctx = *ctx,
|
|
.p0 = p0,
|
|
.p1 = p1
|
|
};
|
|
strncpy(s_last_args_for_mock.func, __func__, sizeof(s_last_args_for_mock.func));
|
|
}
|
|
|
|
void graphics_line_draw_stroked_aa(GContext* ctx, GPoint p0, GPoint p1, uint8_t stroke_width) {
|
|
s_last_args_for_mock = (ArgsForMock){
|
|
.ctx = *ctx,
|
|
.p0 = p0,
|
|
.p1 = p1
|
|
};
|
|
strncpy(s_last_args_for_mock.func, __func__, sizeof(s_last_args_for_mock.func));
|
|
}
|
|
|
|
void graphics_line_draw_stroked_non_aa(GContext* ctx, GPoint p0, GPoint p1, uint8_t stroke_width) {
|
|
s_last_args_for_mock = (ArgsForMock){
|
|
.ctx = *ctx,
|
|
.p0 = p0,
|
|
.p1 = p1
|
|
};
|
|
strncpy(s_last_args_for_mock.func, __func__, sizeof(s_last_args_for_mock.func));
|
|
}
|
|
|
|
void prv_fill_rect_non_aa(GContext* ctx, const GRect *rect, uint16_t radius,
|
|
GCornerMask corner_mask, GColor fill_color) {
|
|
s_last_args_for_mock = (ArgsForMock){
|
|
.ctx = *ctx,
|
|
.r0 = *rect,
|
|
.radius = radius,
|
|
.corner_mask = corner_mask
|
|
};
|
|
strncpy(s_last_args_for_mock.func, __func__, sizeof(s_last_args_for_mock.func));
|
|
}
|
|
|
|
void prv_fill_rect_aa(GContext* ctx, const GRect *rect, uint16_t radius,
|
|
GCornerMask corner_mask, GColor fill_color) {
|
|
s_last_args_for_mock = (ArgsForMock){
|
|
.ctx = *ctx,
|
|
.r0 = *rect,
|
|
.radius = radius,
|
|
.corner_mask = corner_mask
|
|
};
|
|
strncpy(s_last_args_for_mock.func, __func__, sizeof(s_last_args_for_mock.func));
|
|
}
|
|
|
|
void prv_draw_rect(GContext *ctx, const GRect *rect) {
|
|
s_last_args_for_mock = (ArgsForMock){
|
|
.ctx = *ctx,
|
|
.r0 = *rect,
|
|
.radius = 0,
|
|
.corner_mask = GCornerNone
|
|
};
|
|
strncpy(s_last_args_for_mock.func, __func__, sizeof(s_last_args_for_mock.func));
|
|
}
|
|
|
|
void prv_draw_rect_aa_stroked(GContext *ctx, const GRect *rect, uint8_t stroke_width) {
|
|
s_last_args_for_mock = (ArgsForMock){
|
|
.ctx = *ctx,
|
|
.r0 = *rect,
|
|
.radius = 0,
|
|
.corner_mask = GCornerNone
|
|
};
|
|
strncpy(s_last_args_for_mock.func, __func__, sizeof(s_last_args_for_mock.func));
|
|
}
|
|
|
|
void prv_draw_rect_stroked(GContext *ctx, const GRect *rect, uint8_t stroke_width) {
|
|
s_last_args_for_mock = (ArgsForMock){
|
|
.ctx = *ctx,
|
|
.r0 = *rect,
|
|
.radius = 0,
|
|
.corner_mask = GCornerNone
|
|
};
|
|
strncpy(s_last_args_for_mock.func, __func__, sizeof(s_last_args_for_mock.func));
|
|
}
|
|
|
|
void graphics_circle_draw_1px_non_aa(GContext* ctx, GPoint p, uint16_t radius) {
|
|
s_last_args_for_mock = (ArgsForMock){
|
|
.ctx = *ctx,
|
|
.p0 = p,
|
|
.radius = radius
|
|
};
|
|
strncpy(s_last_args_for_mock.func, __func__, sizeof(s_last_args_for_mock.func));
|
|
}
|
|
|
|
void graphics_circle_draw_1px_aa(GContext* ctx, GPoint p, uint16_t radius) {
|
|
s_last_args_for_mock = (ArgsForMock){
|
|
.ctx = *ctx,
|
|
.p0 = p,
|
|
.radius = radius
|
|
};
|
|
strncpy(s_last_args_for_mock.func, __func__, sizeof(s_last_args_for_mock.func));
|
|
}
|
|
|
|
void graphics_circle_draw_stroked_aa(GContext* ctx, GPoint p, uint16_t radius, uint8_t stroke_width) {
|
|
s_last_args_for_mock = (ArgsForMock){
|
|
.ctx = *ctx,
|
|
.p0 = p,
|
|
.radius = radius
|
|
};
|
|
strncpy(s_last_args_for_mock.func, __func__, sizeof(s_last_args_for_mock.func));
|
|
}
|
|
|
|
void graphics_circle_draw_stroked_non_aa(GContext* ctx, GPoint p, uint16_t radius, uint8_t stroke_width) {
|
|
s_last_args_for_mock = (ArgsForMock){
|
|
.ctx = *ctx,
|
|
.p0 = p,
|
|
.radius = radius
|
|
};
|
|
strncpy(s_last_args_for_mock.func, __func__, sizeof(s_last_args_for_mock.func));
|
|
}
|
|
|
|
void graphics_internal_circle_quadrant_fill_aa(GContext* ctx, GPoint p,
|
|
uint16_t radius, GCornerMask quadrant) {
|
|
s_last_args_for_mock = (ArgsForMock){
|
|
.ctx = *ctx,
|
|
.p0 = p,
|
|
.radius = radius,
|
|
.corner_mask = quadrant
|
|
};
|
|
strncpy(s_last_args_for_mock.func, __func__, sizeof(s_last_args_for_mock.func));
|
|
}
|
|
|
|
void graphics_circle_fill_non_aa(GContext* ctx, GPoint p, uint16_t radius) {
|
|
s_last_args_for_mock = (ArgsForMock){
|
|
.ctx = *ctx,
|
|
.p0 = p,
|
|
.radius = radius
|
|
};
|
|
strncpy(s_last_args_for_mock.func, __func__, sizeof(s_last_args_for_mock.func));
|
|
}
|
|
|
|
void prv_draw_round_rect(GContext* ctx, const GRect *rect, uint16_t radius) {
|
|
s_last_args_for_mock = (ArgsForMock){
|
|
.ctx = *ctx,
|
|
.r0 = *rect,
|
|
.radius = radius,
|
|
.corner_mask = GCornersAll
|
|
};
|
|
strncpy(s_last_args_for_mock.func, __func__, sizeof(s_last_args_for_mock.func));
|
|
}
|
|
|
|
void prv_draw_round_rect_aa(GContext* ctx, const GRect *rect, uint16_t radius) {
|
|
s_last_args_for_mock = (ArgsForMock){
|
|
.ctx = *ctx,
|
|
.r0 = *rect,
|
|
.radius = radius,
|
|
.corner_mask = GCornersAll
|
|
};
|
|
strncpy(s_last_args_for_mock.func, __func__, sizeof(s_last_args_for_mock.func));
|
|
}
|
|
|
|
void prv_draw_round_rect_aa_stroked(GContext* ctx, const GRect *rect, uint16_t radius,
|
|
uint8_t stroke_width) {
|
|
s_last_args_for_mock = (ArgsForMock){
|
|
.ctx = *ctx,
|
|
.r0 = *rect,
|
|
.radius = radius,
|
|
.corner_mask = GCornersAll
|
|
};
|
|
strncpy(s_last_args_for_mock.func, __func__, sizeof(s_last_args_for_mock.func));
|
|
}
|
|
|
|
void prv_draw_round_rect_stroked(GContext* ctx, const GRect *rect, uint16_t radius, uint8_t stroke_width) {
|
|
s_last_args_for_mock = (ArgsForMock){
|
|
.ctx = *ctx,
|
|
.r0 = *rect,
|
|
.radius = radius,
|
|
.corner_mask = GCornersAll
|
|
};
|
|
strncpy(s_last_args_for_mock.func, __func__, sizeof(s_last_args_for_mock.func));
|
|
}
|
|
|
|
/////////////////////////////////////
|
|
/// HELPER FUNCTIONS
|
|
/////////////////////////////////////
|
|
// Copy over the last arguments - take the largest possible shape
|
|
static void copy_last_args_for_mock(ArgsForMock *actual_args, ArgsForMock *last_args) {
|
|
memcpy(actual_args, last_args, sizeof(ArgsForMock));
|
|
}
|
|
|
|
// Zero out the arguments from the last run
|
|
static void reset_last_args_for_mock() {
|
|
memset(&s_last_args_for_mock, 0x00, sizeof(s_last_args_for_mock));
|
|
}
|
|
|
|
// Validate the arguments based on the shape that is drawn
|
|
static bool validate_args(ArgsForMock *actual_args, ArgsForMock *valid_args) {
|
|
if (memcmp(actual_args, valid_args, sizeof(ArgsForMock)) == 0) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// This macro will call the expected code_block and then validate the arguments set in code_block
|
|
// match what was expected from the last mock call (i.e. if graphics_draw_line was called, then
|
|
// internally it would call prv_draw_line... and the actual_args would be set to the arguments
|
|
// that are set in prv_draw_line... so when compared to directly calling prv_draw_line..., the two
|
|
// should match.
|
|
#define ASSERT_CALLED(code_block) \
|
|
do {\
|
|
ArgsForMock actual_args; \
|
|
copy_last_args_for_mock(&actual_args, &s_last_args_for_mock); \
|
|
reset_last_args_for_mock(); \
|
|
code_block; \
|
|
bool cmp_result = validate_args(&actual_args, &s_last_args_for_mock); \
|
|
printf("1 %d %d %d %d\n", actual_args.r0.origin.x, actual_args.r0.origin.y, \
|
|
actual_args.r0.size.w, actual_args.r0.size.h); \
|
|
actual_args = s_last_args_for_mock; \
|
|
printf("2 %d %d %d %d\n", actual_args.r0.origin.x, actual_args.r0.origin.y, \
|
|
actual_args.r0.size.w, actual_args.r0.size.h); \
|
|
cl_assert(cmp_result); \
|
|
} while(0)
|
|
|
|
// This is used to make sure nothing has changed when calling code_block
|
|
// i.e. no prv_... functions have been called
|
|
// If any prv_... functions are called then s_last_args_for_mock will be updated
|
|
#define ASSERT_NO_CHANGE(code_block) \
|
|
do {\
|
|
ArgsForMock actual_args; \
|
|
reset_last_args_for_mock(); \
|
|
copy_last_args_for_mock(&actual_args, &s_last_args_for_mock); \
|
|
code_block; \
|
|
bool cmp_result = validate_args(&actual_args, &s_last_args_for_mock); \
|
|
cl_assert(cmp_result); \
|
|
} while(0)
|
|
|
|
static void setup_test(GContext* ctx, bool antialiased, uint8_t stroke_width, GColor stroke_color,
|
|
GColor fill_color, bool lock) {
|
|
graphics_context_set_antialiased(ctx, antialiased);
|
|
graphics_context_set_stroke_width(ctx, stroke_width);
|
|
graphics_context_set_stroke_color(ctx, stroke_color);
|
|
graphics_context_set_fill_color(ctx, fill_color);
|
|
ctx->lock = lock;
|
|
reset_last_args_for_mock();
|
|
}
|
|
|
|
// Setup
|
|
void test_graphics_context_${BIT_DEPTH_NAME}__initialize(void) {
|
|
fb = malloc(sizeof(FrameBuffer));
|
|
framebuffer_init(fb, &(GSize) {DISP_COLS, DISP_ROWS});
|
|
test_graphics_context_init(&context, fb);
|
|
}
|
|
|
|
// Teardown
|
|
void test_graphics_context_${BIT_DEPTH_NAME}__cleanup(void) {
|
|
free(fb);
|
|
}
|
|
|
|
/////////////////////////////////////
|
|
/// TESTS
|
|
/////////////////////////////////////
|
|
void test_graphics_context_${BIT_DEPTH_NAME}__set(void) {
|
|
GDrawState draw_state;
|
|
GColor color;
|
|
|
|
// Stroke Color
|
|
graphics_context_set_stroke_color(&context, GColorClear);
|
|
cl_assert_equal_i(context.draw_state.stroke_color.argb, GColorClear.argb);
|
|
|
|
color = GColorBlue;
|
|
graphics_context_set_stroke_color(&context, color);
|
|
#if PBL_COLOR
|
|
cl_assert_equal_i(context.draw_state.stroke_color.argb, GColorBlue.argb);
|
|
#else
|
|
cl_assert_equal_i(context.draw_state.stroke_color.argb, GColorBlack.argb);
|
|
#endif
|
|
|
|
color.a = 2;
|
|
graphics_context_set_stroke_color(&context, color);
|
|
#if PBL_COLOR
|
|
cl_assert_equal_i(context.draw_state.stroke_color.argb, GColorBlue.argb);
|
|
#else
|
|
cl_assert_equal_i(context.draw_state.stroke_color.argb, GColorBlack.argb);
|
|
#endif
|
|
|
|
color.a = 1;
|
|
graphics_context_set_stroke_color(&context, color);
|
|
cl_assert_equal_i(context.draw_state.stroke_color.argb, GColorClear.argb);
|
|
|
|
color.a = 0;
|
|
graphics_context_set_stroke_color(&context, color);
|
|
cl_assert_equal_i(context.draw_state.stroke_color.argb, GColorClear.argb);
|
|
|
|
// Stroke Color - 2-bit
|
|
graphics_context_set_stroke_color_2bit(&context, GColor2Black);
|
|
cl_assert(gcolor_equal(context.draw_state.stroke_color, GColorBlack));
|
|
|
|
// Fill Color
|
|
graphics_context_set_fill_color(&context, GColorClear);
|
|
cl_assert_equal_i(context.draw_state.fill_color.argb, GColorClear.argb);
|
|
|
|
color = GColorOrange;
|
|
graphics_context_set_fill_color(&context, color);
|
|
#if PBL_COLOR
|
|
cl_assert_equal_i(context.draw_state.fill_color.argb, GColorOrange.argb);
|
|
#else
|
|
cl_assert_equal_i(context.draw_state.fill_color.argb, GColorDarkGray.argb);
|
|
#endif
|
|
|
|
color.a = 2;
|
|
graphics_context_set_fill_color(&context, color);
|
|
#if PBL_COLOR
|
|
cl_assert_equal_i(context.draw_state.fill_color.argb, GColorOrange.argb);
|
|
#else
|
|
cl_assert_equal_i(context.draw_state.fill_color.argb, GColorDarkGray.argb);
|
|
#endif
|
|
|
|
color.a = 1;
|
|
graphics_context_set_fill_color(&context, color);
|
|
cl_assert_equal_i(context.draw_state.fill_color.argb, GColorClear.argb);
|
|
|
|
color.a = 0;
|
|
graphics_context_set_fill_color(&context, color);
|
|
cl_assert_equal_i(context.draw_state.fill_color.argb, GColorClear.argb);
|
|
|
|
// Fill Color - 2-bit
|
|
graphics_context_set_fill_color_2bit(&context, GColor2White);
|
|
cl_assert(gcolor_equal(context.draw_state.fill_color, GColorWhite));
|
|
|
|
// Compositing Mode
|
|
graphics_context_set_compositing_mode(&context, GCompOpOr);
|
|
cl_assert(context.draw_state.compositing_mode == GCompOpOr);
|
|
|
|
// Text Color
|
|
graphics_context_set_text_color(&context, GColorClear);
|
|
cl_assert_equal_i(context.draw_state.text_color.argb, GColorClear.argb);
|
|
|
|
color = GColorYellow;
|
|
graphics_context_set_text_color(&context, color);
|
|
#if PBL_COLOR
|
|
cl_assert_equal_i(context.draw_state.text_color.argb, GColorYellow.argb);
|
|
#else
|
|
cl_assert_equal_i(context.draw_state.text_color.argb, GColorWhite.argb);
|
|
#endif
|
|
|
|
color.a = 2;
|
|
graphics_context_set_text_color(&context, color);
|
|
#if PBL_COLOR
|
|
cl_assert_equal_i(context.draw_state.text_color.argb, GColorYellow.argb);
|
|
#else
|
|
cl_assert_equal_i(context.draw_state.text_color.argb, GColorWhite.argb);
|
|
#endif
|
|
|
|
color.a = 1;
|
|
graphics_context_set_text_color(&context, color);
|
|
cl_assert_equal_i(context.draw_state.text_color.argb, GColorClear.argb);
|
|
|
|
color.a = 0;
|
|
graphics_context_set_text_color(&context, color);
|
|
cl_assert_equal_i(context.draw_state.text_color.argb, GColorClear.argb);
|
|
|
|
// Text Color - 2-bit
|
|
graphics_context_set_text_color_2bit(&context, GColor2White);
|
|
cl_assert(gcolor_equal(context.draw_state.text_color, GColorWhite));
|
|
|
|
#if PBL_COLOR
|
|
// Antialiased
|
|
graphics_context_set_antialiased(&context, true);
|
|
cl_assert(context.draw_state.antialiased == true);
|
|
#endif
|
|
|
|
// Stroke Width
|
|
graphics_context_set_stroke_width(&context, 11);
|
|
cl_assert(context.draw_state.stroke_width == 11);
|
|
|
|
// Make sure setting to zero is ignored
|
|
draw_state = graphics_context_get_drawing_state(&context);
|
|
graphics_context_set_stroke_width(&context, 0);
|
|
cl_assert(memcmp(&draw_state, &context.draw_state, sizeof(GDrawState)) == 0);
|
|
|
|
// Check draw state
|
|
memset(&draw_state, 0x5A, sizeof(GDrawState));
|
|
graphics_context_set_drawing_state(&context, draw_state);
|
|
cl_assert(memcmp(&draw_state, &context.draw_state, sizeof(GDrawState)) == 0);
|
|
}
|
|
|
|
void test_graphics_context_${BIT_DEPTH_NAME}__draw_antialiased(void) {
|
|
// Stroke width = 1, antialiased
|
|
setup_test(&context, true, 1, GColorBlack, GColorBlack, false);
|
|
graphics_draw_line(&context, GPoint(5, 5), GPoint(45, 10));
|
|
#if PBL_COLOR
|
|
ASSERT_CALLED(graphics_line_draw_1px_aa(&context, GPoint(5, 5), GPoint(45, 10)));
|
|
#else
|
|
ASSERT_CALLED(graphics_line_draw_1px_non_aa(&context, GPoint(5, 5), GPoint(45, 10)));
|
|
#endif
|
|
|
|
setup_test(&context, true, 1, GColorBlack, GColorBlack, false);
|
|
graphics_draw_rect(&context, &GRect(10, 20, 40, 10));
|
|
ASSERT_CALLED(prv_draw_rect(&context, &GRect(10, 20, 40, 10)));
|
|
|
|
setup_test(&context, true, 1, GColorBlack, GColorBlack, false);
|
|
graphics_draw_circle(&context, GPoint(50, 50), 10);
|
|
#if PBL_COLOR
|
|
ASSERT_CALLED(graphics_circle_draw_1px_aa(&context, GPoint(50, 50), 10));
|
|
#else
|
|
ASSERT_CALLED(graphics_circle_draw_1px_non_aa(&context, GPoint(50, 50), 10));
|
|
#endif
|
|
|
|
setup_test(&context, true, 1, GColorBlack, GColorBlack, false);
|
|
graphics_draw_round_rect(&context, &GRect(20, 80, 40, 10), 4);
|
|
#if PBL_COLOR
|
|
ASSERT_CALLED(prv_draw_round_rect_aa(&context, &GRect(20, 80, 40, 10), 4));
|
|
#else
|
|
ASSERT_CALLED(prv_draw_round_rect(&context, &GRect(20, 80, 40, 10), 4));
|
|
#endif
|
|
}
|
|
|
|
|
|
void test_graphics_context_${BIT_DEPTH_NAME}__draw_stroke_width_1(void) {
|
|
// Stroke width 1, non-antialiased
|
|
setup_test(&context, false, 1, GColorBlack, GColorBlack, false);
|
|
graphics_draw_line(&context, GPoint(5, 5), GPoint(45, 10));
|
|
ASSERT_CALLED(graphics_line_draw_1px_non_aa(&context, GPoint(5, 5), GPoint(45, 10)));
|
|
|
|
setup_test(&context, false, 1, GColorBlack, GColorBlack, false);
|
|
graphics_draw_rect(&context, &GRect(10, 20, 40, 10));
|
|
ASSERT_CALLED(prv_draw_rect(&context, &GRect(10, 20, 40, 10)));
|
|
|
|
setup_test(&context, false, 1, GColorBlack, GColorBlack, false);
|
|
graphics_draw_circle(&context, GPoint(50, 50), 10);
|
|
ASSERT_CALLED(graphics_circle_draw_1px_non_aa(&context, GPoint(50, 50), 10));
|
|
|
|
setup_test(&context, false, 1, GColorBlack, GColorBlack, false);
|
|
graphics_draw_round_rect(&context, &GRect(20, 80, 40, 10), 4);
|
|
ASSERT_CALLED(prv_draw_round_rect(&context, &GRect(20, 80, 40, 10), 4));
|
|
}
|
|
|
|
void test_graphics_context_${BIT_DEPTH_NAME}__draw_stroke_width_2(void) {
|
|
// Stroke width 2, non-antialiased
|
|
setup_test(&context, false, 2, GColorBlack, GColorBlack, false);
|
|
graphics_draw_line(&context, GPoint(5, 5), GPoint(45, 10));
|
|
ASSERT_CALLED(graphics_line_draw_stroked_non_aa(&context, GPoint(5, 5), GPoint(45, 10), 2));
|
|
|
|
setup_test(&context, false, 2, GColorBlack, GColorBlack, false);
|
|
graphics_draw_rect(&context, &GRect(10, 20, 40, 10));
|
|
ASSERT_CALLED(prv_draw_rect(&context, &GRect(10, 20, 40, 10)));
|
|
|
|
setup_test(&context, false, 2, GColorBlack, GColorBlack, false);
|
|
graphics_draw_circle(&context, GPoint(50, 50), 10);
|
|
ASSERT_CALLED(graphics_circle_draw_stroked_non_aa(&context, GPoint(50, 50), 10, 2));
|
|
|
|
setup_test(&context, false, 2, GColorBlack, GColorBlack, false);
|
|
graphics_draw_round_rect(&context, &GRect(20, 80, 40, 10), 4);
|
|
ASSERT_CALLED(prv_draw_round_rect_stroked(&context, &GRect(20, 80, 40, 10), 4, 2));
|
|
}
|
|
|
|
void test_graphics_context_${BIT_DEPTH_NAME}__draw_stroke_width_even(void) {
|
|
// Stroke width even > 2, non-antialiased
|
|
setup_test(&context, false, SW_EVEN, GColorBlack, GColorBlack, false);
|
|
graphics_draw_line(&context, GPoint(5, 5), GPoint(45, 10));
|
|
ASSERT_CALLED(graphics_line_draw_stroked_non_aa(&context, GPoint(5, 5), GPoint(45, 10), SW_EVEN));
|
|
|
|
setup_test(&context, false, SW_EVEN, GColorBlack, GColorBlack, false);
|
|
graphics_draw_rect(&context, &GRect(10, 20, 40, 10));
|
|
ASSERT_CALLED(prv_draw_rect_stroked(&context, &GRect(10, 20, 40, 10), SW_EVEN));
|
|
|
|
setup_test(&context, false, SW_EVEN, GColorBlack, GColorBlack, false);
|
|
graphics_draw_circle(&context, GPoint(50, 50), 10);
|
|
ASSERT_CALLED(graphics_circle_draw_stroked_non_aa(&context, GPoint(50, 50), 10, SW_EVEN));
|
|
|
|
setup_test(&context, false, SW_EVEN, GColorBlack, GColorBlack, false);
|
|
graphics_draw_round_rect(&context, &GRect(20, 80, 40, 10), 4);
|
|
ASSERT_CALLED(prv_draw_round_rect_stroked(&context, &GRect(20, 80, 40, 10), 4, SW_EVEN));
|
|
}
|
|
|
|
void test_graphics_context_${BIT_DEPTH_NAME}__draw_stroke_width_odd(void) {
|
|
// Stroke width odd > 1, non-antialiased
|
|
setup_test(&context, false, SW_ODD, GColorBlack, GColorBlack, false);
|
|
graphics_draw_line(&context, GPoint(5, 5), GPoint(45, 10));
|
|
ASSERT_CALLED(graphics_line_draw_stroked_non_aa(&context, GPoint(5, 5), GPoint(45, 10), SW_ODD));
|
|
|
|
setup_test(&context, false, SW_ODD, GColorBlack, GColorBlack, false);
|
|
graphics_draw_rect(&context, &GRect(10, 20, 40, 10));
|
|
ASSERT_CALLED(prv_draw_rect_stroked(&context, &GRect(10, 20, 40, 10), SW_ODD));
|
|
|
|
setup_test(&context, false, SW_ODD, GColorBlack, GColorBlack, false);
|
|
graphics_draw_circle(&context, GPoint(50, 50), 10);
|
|
ASSERT_CALLED(graphics_circle_draw_stroked_non_aa(&context, GPoint(50, 50), 10, SW_ODD));
|
|
|
|
setup_test(&context, false, SW_ODD, GColorBlack, GColorBlack, false);
|
|
graphics_draw_round_rect(&context, &GRect(20, 80, 40, 10), 4);
|
|
ASSERT_CALLED(prv_draw_round_rect_stroked(&context, &GRect(20, 80, 40, 10), 4, SW_ODD));
|
|
}
|
|
|
|
void test_graphics_context_${BIT_DEPTH_NAME}__draw_antialiased_stroke_width_2(void) {
|
|
// Stroke width = 2, antialiased
|
|
setup_test(&context, true, 2, GColorBlack, GColorBlack, false);
|
|
graphics_draw_line(&context, GPoint(5, 5), GPoint(45, 10));
|
|
#if PBL_COLOR
|
|
ASSERT_CALLED(graphics_line_draw_stroked_aa(&context, GPoint(5, 5), GPoint(45, 10), 2));
|
|
#else
|
|
ASSERT_CALLED(graphics_line_draw_stroked_non_aa(&context, GPoint(5, 5), GPoint(45, 10), 2));
|
|
#endif
|
|
setup_test(&context, true, 2, GColorBlack, GColorBlack, false);
|
|
graphics_draw_rect(&context, &GRect(10, 20, 40, 10));
|
|
ASSERT_CALLED(prv_draw_rect(&context, &GRect(10, 20, 40, 10)));
|
|
|
|
setup_test(&context, true, 2, GColorBlack, GColorBlack, false);
|
|
graphics_draw_circle(&context, GPoint(50, 50), 10);
|
|
#if PBL_COLOR
|
|
ASSERT_CALLED(graphics_circle_draw_stroked_aa(&context, GPoint(50, 50), 10, 2));
|
|
#else
|
|
ASSERT_CALLED(graphics_circle_draw_stroked_non_aa(&context, GPoint(50, 50), 10, 2));
|
|
#endif
|
|
|
|
setup_test(&context, true, 2, GColorBlack, GColorBlack, false);
|
|
graphics_draw_round_rect(&context, &GRect(20, 80, 40, 10), 4);
|
|
#if PBL_COLOR
|
|
ASSERT_CALLED(prv_draw_round_rect_aa_stroked(&context, &GRect(20, 80, 40, 10), 4, 2));
|
|
#else
|
|
ASSERT_CALLED(prv_draw_round_rect_stroked(&context, &GRect(20, 80, 40, 10), 4, 2));
|
|
#endif
|
|
}
|
|
|
|
void test_graphics_context_${BIT_DEPTH_NAME}__draw_antialiased_stroke_width_even(void) {
|
|
// Stroke width even > 2, antialiased
|
|
setup_test(&context, true, SW_EVEN, GColorBlack, GColorBlack, false);
|
|
graphics_draw_line(&context, GPoint(5, 5), GPoint(45, 10));
|
|
#if PBL_COLOR
|
|
ASSERT_CALLED(graphics_line_draw_stroked_aa(&context, GPoint(5, 5), GPoint(45, 10), SW_EVEN));
|
|
#else
|
|
ASSERT_CALLED(graphics_line_draw_stroked_non_aa(&context, GPoint(5, 5), GPoint(45, 10), SW_EVEN));
|
|
#endif
|
|
|
|
setup_test(&context, true, SW_EVEN, GColorBlack, GColorBlack, false);
|
|
graphics_draw_rect(&context, &GRect(10, 20, 40, 10));
|
|
#if PBL_COLOR
|
|
ASSERT_CALLED(prv_draw_rect_aa_stroked(&context, &GRect(10, 20, 40, 10), SW_EVEN));
|
|
#else
|
|
ASSERT_CALLED(prv_draw_rect_stroked(&context, &GRect(10, 20, 40, 10), SW_EVEN));
|
|
#endif
|
|
|
|
setup_test(&context, true, SW_EVEN, GColorBlack, GColorBlack, false);
|
|
graphics_draw_circle(&context, GPoint(50, 50), 10);
|
|
#if PBL_COLOR
|
|
ASSERT_CALLED(graphics_circle_draw_stroked_aa(&context, GPoint(50, 50), 10, SW_EVEN));
|
|
#else
|
|
ASSERT_CALLED(graphics_circle_draw_stroked_non_aa(&context, GPoint(50, 50), 10, SW_EVEN));
|
|
#endif
|
|
|
|
setup_test(&context, true, SW_EVEN, GColorBlack, GColorBlack, false);
|
|
graphics_draw_round_rect(&context, &GRect(20, 80, 40, 10), 4);
|
|
#if PBL_COLOR
|
|
ASSERT_CALLED(prv_draw_round_rect_aa_stroked(&context, &GRect(20, 80, 40, 10), 4, SW_EVEN));
|
|
#else
|
|
ASSERT_CALLED(prv_draw_round_rect_stroked(&context, &GRect(20, 80, 40, 10), 4, SW_EVEN));
|
|
#endif
|
|
}
|
|
|
|
void test_graphics_context_${BIT_DEPTH_NAME}__draw_antialiased_stroke_width_odd(void) {
|
|
// Stroke width odd > 1, antialiased
|
|
setup_test(&context, true, SW_ODD, GColorBlack, GColorBlack, false);
|
|
graphics_draw_line(&context, GPoint(5, 5), GPoint(45, 10));
|
|
#if PBL_COLOR
|
|
ASSERT_CALLED(graphics_line_draw_stroked_aa(&context, GPoint(5, 5), GPoint(45, 10), SW_ODD));
|
|
#else
|
|
ASSERT_CALLED(graphics_line_draw_stroked_non_aa(&context, GPoint(5, 5), GPoint(45, 10), SW_ODD));
|
|
#endif
|
|
|
|
setup_test(&context, true, SW_ODD, GColorBlack, GColorBlack, false);
|
|
graphics_draw_rect(&context, &GRect(10, 20, 40, 10));
|
|
#if PBL_COLOR
|
|
ASSERT_CALLED(prv_draw_rect_aa_stroked(&context, &GRect(10, 20, 40, 10), SW_ODD));
|
|
#else
|
|
ASSERT_CALLED(prv_draw_rect_stroked(&context, &GRect(10, 20, 40, 10), SW_ODD));
|
|
#endif
|
|
|
|
setup_test(&context, true, SW_ODD, GColorBlack, GColorBlack, false);
|
|
graphics_draw_circle(&context, GPoint(50, 50), 10);
|
|
#if PBL_COLOR
|
|
ASSERT_CALLED(graphics_circle_draw_stroked_aa(&context, GPoint(50, 50), 10, SW_ODD));
|
|
#else
|
|
ASSERT_CALLED(graphics_circle_draw_stroked_non_aa(&context, GPoint(50, 50), 10, SW_ODD));
|
|
#endif
|
|
|
|
setup_test(&context, true, SW_ODD, GColorBlack, GColorBlack, false);
|
|
graphics_draw_round_rect(&context, &GRect(20, 80, 40, 10), 4);
|
|
#if PBL_COLOR
|
|
ASSERT_CALLED(prv_draw_round_rect_aa_stroked(&context, &GRect(20, 80, 40, 10), 4, SW_ODD));
|
|
#else
|
|
ASSERT_CALLED(prv_draw_round_rect_stroked(&context, &GRect(20, 80, 40, 10), 4, SW_ODD));
|
|
#endif
|
|
}
|
|
|
|
void test_graphics_context_${BIT_DEPTH_NAME}__fill(void) {
|
|
// Fill shape, non-antialiased (Stroke width/color N/A)
|
|
setup_test(&context, false, 5, GColorBlack, GColorBlack, false);
|
|
graphics_fill_rect(&context, &GRect(10, 20, 40, 10));
|
|
ASSERT_CALLED(prv_fill_rect_non_aa(&context, &GRect(10, 20, 40, 10), 0, GCornerNone, GColorBlack));
|
|
|
|
setup_test(&context, false, 5, GColorBlack, GColorBlack, false);
|
|
graphics_fill_circle(&context, GPoint(50, 50), 10);
|
|
ASSERT_CALLED(graphics_circle_fill_non_aa(&context, GPoint(50, 50), 10));
|
|
|
|
setup_test(&context, false, 5, GColorBlack, GColorBlack, false);
|
|
graphics_fill_round_rect(&context, &GRect(20, 80, 40, 10), 4, GCornersAll);
|
|
ASSERT_CALLED(prv_fill_rect_non_aa(&context, &GRect(20, 80, 40, 10), 4, GCornersAll, GColorBlack));
|
|
}
|
|
|
|
void test_graphics_context_${BIT_DEPTH_NAME}__fill_antialiased(void) {
|
|
// Fill shape, antialiased (Stroke width/color N/A)
|
|
|
|
setup_test(&context, true, 5, GColorBlack, GColorBlack, false);
|
|
graphics_fill_rect(&context, &GRect(10, 20, 40, 10));
|
|
#if SCREEN_COLOR_DEPTH_BITS == 1
|
|
ASSERT_CALLED(prv_fill_rect_non_aa(&context, &GRect(10, 20, 40, 10), 0, GCornerNone, GColorBlack));
|
|
#else
|
|
ASSERT_CALLED(prv_fill_rect_aa(&context, &GRect(10, 20, 40, 10), 0, GCornerNone, GColorBlack));
|
|
#endif
|
|
|
|
setup_test(&context, true, 5, GColorBlack, GColorBlack, false);
|
|
graphics_fill_circle(&context, GPoint(50, 50), 10);
|
|
#if PBL_COLOR
|
|
ASSERT_CALLED(graphics_internal_circle_quadrant_fill_aa(&context, GPoint(50, 50), 10, GCornersAll));
|
|
#else
|
|
ASSERT_CALLED(graphics_circle_fill_non_aa(&context, GPoint(50, 50), 10));
|
|
#endif
|
|
|
|
setup_test(&context, true, 5, GColorBlack, GColorBlack, false);
|
|
graphics_fill_round_rect(&context, &GRect(20, 80, 40, 10), 4, GCornersAll);
|
|
#if SCREEN_COLOR_DEPTH_BITS == 1
|
|
ASSERT_CALLED(prv_fill_rect_non_aa(&context, &GRect(20, 80, 40, 10), 4, GCornersAll, GColorBlack));
|
|
#else
|
|
ASSERT_CALLED(prv_fill_rect_aa(&context, &GRect(20, 80, 40, 10), 4, GCornersAll, GColorBlack));
|
|
#endif
|
|
}
|
|
|
|
void test_graphics_context_${BIT_DEPTH_NAME}__lock(void) {
|
|
// Test all the setup test combinations as above
|
|
setup_test(&context, false, 1, GColorBlack, GColorBlack, true);
|
|
ASSERT_NO_CHANGE(graphics_draw_line(&context, GPoint(5, 5), GPoint(45, 10)));
|
|
ASSERT_NO_CHANGE(graphics_draw_rect(&context, &GRect(10, 20, 40, 10)));
|
|
ASSERT_NO_CHANGE(graphics_draw_circle(&context, GPoint(50, 50), 10));
|
|
ASSERT_NO_CHANGE(graphics_draw_round_rect(&context, &GRect(20, 80, 40, 10), 4));
|
|
|
|
setup_test(&context, false, 2, GColorBlack, GColorBlack, true);
|
|
ASSERT_NO_CHANGE(graphics_draw_line(&context, GPoint(5, 5), GPoint(45, 10)));
|
|
ASSERT_NO_CHANGE(graphics_draw_rect(&context, &GRect(10, 20, 40, 10)));
|
|
ASSERT_NO_CHANGE(graphics_draw_circle(&context, GPoint(50, 50), 10));
|
|
ASSERT_NO_CHANGE(graphics_draw_round_rect(&context, &GRect(20, 80, 40, 10), 4));
|
|
|
|
setup_test(&context, false, SW_EVEN, GColorBlack, GColorBlack, true);
|
|
ASSERT_NO_CHANGE(graphics_draw_line(&context, GPoint(5, 5), GPoint(45, 10)));
|
|
ASSERT_NO_CHANGE(graphics_draw_rect(&context, &GRect(10, 20, 40, 10)));
|
|
ASSERT_NO_CHANGE(graphics_draw_circle(&context, GPoint(50, 50), 10));
|
|
ASSERT_NO_CHANGE(graphics_draw_round_rect(&context, &GRect(20, 80, 40, 10), 4));
|
|
|
|
setup_test(&context, false, SW_ODD, GColorBlack, GColorBlack, true);
|
|
ASSERT_NO_CHANGE(graphics_draw_line(&context, GPoint(5, 5), GPoint(45, 10)));
|
|
ASSERT_NO_CHANGE(graphics_draw_rect(&context, &GRect(10, 20, 40, 10)));
|
|
ASSERT_NO_CHANGE(graphics_draw_circle(&context, GPoint(50, 50), 10));
|
|
ASSERT_NO_CHANGE(graphics_draw_round_rect(&context, &GRect(20, 80, 40, 10), 4));
|
|
ASSERT_NO_CHANGE(graphics_fill_rect(&context, &GRect(10, 20, 40, 10)));
|
|
ASSERT_NO_CHANGE(graphics_fill_circle(&context, GPoint(50, 50), 10));
|
|
ASSERT_NO_CHANGE(graphics_fill_round_rect(&context, &GRect(20, 80, 40, 10), 4, GCornersAll));
|
|
|
|
setup_test(&context, true, 1, GColorBlack, GColorBlack, true);
|
|
ASSERT_NO_CHANGE(graphics_draw_line(&context, GPoint(5, 5), GPoint(45, 10)));
|
|
ASSERT_NO_CHANGE(graphics_draw_rect(&context, &GRect(10, 20, 40, 10)));
|
|
ASSERT_NO_CHANGE(graphics_draw_circle(&context, GPoint(50, 50), 10));
|
|
ASSERT_NO_CHANGE(graphics_draw_round_rect(&context, &GRect(20, 80, 40, 10), 4));
|
|
|
|
setup_test(&context, true, 2, GColorBlack, GColorBlack, true);
|
|
ASSERT_NO_CHANGE(graphics_draw_line(&context, GPoint(5, 5), GPoint(45, 10)));
|
|
ASSERT_NO_CHANGE(graphics_draw_rect(&context, &GRect(10, 20, 40, 10)));
|
|
ASSERT_NO_CHANGE(graphics_draw_circle(&context, GPoint(50, 50), 10));
|
|
ASSERT_NO_CHANGE(graphics_draw_round_rect(&context, &GRect(20, 80, 40, 10), 4));
|
|
|
|
setup_test(&context, true, SW_EVEN, GColorBlack, GColorBlack, true);
|
|
ASSERT_NO_CHANGE(graphics_draw_line(&context, GPoint(5, 5), GPoint(45, 10)));
|
|
ASSERT_NO_CHANGE(graphics_draw_rect(&context, &GRect(10, 20, 40, 10)));
|
|
ASSERT_NO_CHANGE(graphics_draw_circle(&context, GPoint(50, 50), 10));
|
|
ASSERT_NO_CHANGE(graphics_draw_round_rect(&context, &GRect(20, 80, 40, 10), 4));
|
|
|
|
setup_test(&context, true, SW_ODD, GColorBlack, GColorBlack, true);
|
|
ASSERT_NO_CHANGE(graphics_draw_line(&context, GPoint(5, 5), GPoint(45, 10)));
|
|
ASSERT_NO_CHANGE(graphics_draw_rect(&context, &GRect(10, 20, 40, 10)));
|
|
ASSERT_NO_CHANGE(graphics_draw_circle(&context, GPoint(50, 50), 10));
|
|
ASSERT_NO_CHANGE(graphics_draw_round_rect(&context, &GRect(20, 80, 40, 10), 4));
|
|
ASSERT_NO_CHANGE(graphics_fill_rect(&context, &GRect(10, 20, 40, 10)));
|
|
ASSERT_NO_CHANGE(graphics_fill_circle(&context, GPoint(50, 50), 10));
|
|
ASSERT_NO_CHANGE(graphics_fill_round_rect(&context, &GRect(20, 80, 40, 10), 4, GCornersAll));
|
|
}
|
|
|
|
void test_graphics_context_${BIT_DEPTH_NAME}__lock_context(void) {
|
|
GDrawState draw_state;
|
|
context.lock = true;
|
|
|
|
// Stroke Color
|
|
draw_state = graphics_context_get_drawing_state(&context);
|
|
graphics_context_set_stroke_color(&context, GColorBlue);
|
|
cl_assert(memcmp(&draw_state, &context.draw_state, sizeof(GDrawState)) == 0);
|
|
|
|
// Fill Color
|
|
draw_state = graphics_context_get_drawing_state(&context);
|
|
graphics_context_set_fill_color(&context, GColorGreen);
|
|
cl_assert(memcmp(&draw_state, &context.draw_state, sizeof(GDrawState)) == 0);
|
|
|
|
// Compositing Mode
|
|
draw_state = graphics_context_get_drawing_state(&context);
|
|
graphics_context_set_compositing_mode(&context, GCompOpOr);
|
|
cl_assert(memcmp(&draw_state, &context.draw_state, sizeof(GDrawState)) == 0);
|
|
|
|
// Text Color
|
|
draw_state = graphics_context_get_drawing_state(&context);
|
|
graphics_context_set_text_color(&context, GColorRed);
|
|
cl_assert(memcmp(&draw_state, &context.draw_state, sizeof(GDrawState)) == 0);
|
|
|
|
// Antialiased
|
|
draw_state = graphics_context_get_drawing_state(&context);
|
|
graphics_context_set_antialiased(&context, true);
|
|
cl_assert(memcmp(&draw_state, &context.draw_state, sizeof(GDrawState)) == 0);
|
|
|
|
// Stroke Width
|
|
draw_state = graphics_context_get_drawing_state(&context);
|
|
graphics_context_set_stroke_width(&context, 11);
|
|
cl_assert(memcmp(&draw_state, &context.draw_state, sizeof(GDrawState)) == 0);
|
|
}
|
|
|
|
void test_graphics_context_${BIT_DEPTH_NAME}__lock_framebuffer(void) {
|
|
FrameBuffer fb = {};
|
|
framebuffer_init(&fb, &(GSize) {DISP_COLS, DISP_ROWS});
|
|
GContext ctx = {.dest_bitmap.info = {
|
|
.format = GBITMAP_NATIVE_FORMAT,
|
|
.version = GBITMAP_VERSION_CURRENT,
|
|
}, .parent_framebuffer=&fb};
|
|
GBitmap *framebuffer = graphics_capture_frame_buffer(&ctx);
|
|
cl_assert(ctx.lock == true);
|
|
cl_assert_equal_p(framebuffer, &ctx.dest_bitmap);
|
|
|
|
// Test releasing on any platform
|
|
cl_assert(fb.is_dirty == false);
|
|
graphics_release_frame_buffer(&ctx, framebuffer);
|
|
cl_assert(ctx.lock == false);
|
|
cl_assert(fb.is_dirty == true);
|
|
};
|
|
|
|
void test_graphics_context_${BIT_DEPTH_NAME}__lock_framebuffer_8BitCircular(void) {
|
|
// Test for locking of requested framebuffer format
|
|
GContext ctx = {.dest_bitmap.info.format = GBitmapFormat8BitCircular};
|
|
GBitmap *bmp = graphics_capture_frame_buffer_format(&ctx, GBitmapFormat8BitCircular);
|
|
cl_assert_equal_p(bmp, &ctx.dest_bitmap);
|
|
cl_assert(ctx.lock == true);
|
|
};
|
|
|
|
void test_graphics_context_${BIT_DEPTH_NAME}__lock_framebuffer_fails_from_8BitCircular(void) {
|
|
// Test for locking of 8Bit Circular framebuffer when framebuffer is regular 8Bit
|
|
GContext ctx = {.dest_bitmap.info.format = GBitmapFormat8BitCircular};
|
|
GBitmap *bmp = graphics_capture_frame_buffer_format(&ctx, GBitmapFormat8Bit);
|
|
cl_assert(ctx.lock == false);
|
|
cl_assert_equal_p(bmp, NULL);
|
|
};
|
|
|
|
void test_graphics_context_${BIT_DEPTH_NAME}__lock_framebuffer_1Bit_on_8BitCircular_must_fail(void) {
|
|
// Test for locking of 1Bit framebuffer when frambuffer is 8Bit Circular
|
|
GContext ctx = {.dest_bitmap.info.format = GBitmapFormat8BitCircular};
|
|
GBitmap *bmp = graphics_capture_frame_buffer_format(&ctx, GBitmapFormat1Bit);
|
|
cl_assert(ctx.lock == false);
|
|
cl_assert_equal_p(bmp, NULL);
|
|
};
|
|
|
|
void test_graphics_context_${BIT_DEPTH_NAME}__lock_framebuffer_2BitPalette_must_fail(void) {
|
|
// Ensure that the code path for unsupported capture formats leaves the GContext unlocked.
|
|
GContext ctx = {.dest_bitmap.info.format = GBitmapFormat8Bit};
|
|
GBitmap *bmp = graphics_capture_frame_buffer_format(&ctx, GBitmapFormat2BitPalette);
|
|
cl_assert(ctx.lock == false);
|
|
cl_assert_equal_p(bmp, NULL);
|
|
}
|