mirror of
https://github.com/google/pebble.git
synced 2025-06-03 16:53:11 +00:00
Import of the watch repository from Pebble
This commit is contained in:
commit
3b92768480
10334 changed files with 2564465 additions and 0 deletions
118
tests/fw/graphics/test_perimeter.c
Normal file
118
tests/fw/graphics/test_perimeter.c
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* 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/perimeter.h"
|
||||
|
||||
#include "clar.h"
|
||||
#include "util/trig.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <math.h>
|
||||
#ifndef M_PI
|
||||
// M_PI doesn't exist in Linux
|
||||
#define M_PI 3.14159265358979323846 /* pi */
|
||||
#endif
|
||||
#define DEG2RAD(a) (M_PI/180*(a))
|
||||
|
||||
// Stubs
|
||||
////////////////////////////////////
|
||||
#include "stubs_heap.h"
|
||||
#include "stubs_passert.h"
|
||||
#include "stubs_logging.h"
|
||||
#include "stubs_app_state.h"
|
||||
#include "stubs_compiled_with_legacy2_sdk.h"
|
||||
|
||||
#define BETWEEN(val, low, high) \
|
||||
(val >= low && val <= high) ? true : false
|
||||
|
||||
// Tests
|
||||
////////////////////////////////////
|
||||
|
||||
GRangeHorizontal perimeter_for_circle(GRangeVertical vertical_range, GPoint center, int32_t radius);
|
||||
GRangeHorizontal perimeter_for_display_round(const GPerimeter *perimeter,
|
||||
const GSize *ctx_size,
|
||||
GRangeVertical vertical_range,
|
||||
uint16_t inset);
|
||||
GRangeHorizontal perimeter_for_display_rect(const GPerimeter *perimeter,
|
||||
const GSize *ctx_size,
|
||||
GRangeVertical vertical_range,
|
||||
uint16_t inset);
|
||||
|
||||
void test_perimeter__perimeter_for_circle(void) {
|
||||
GRect bounds = GRect(0,0,180,180);
|
||||
GPoint center = grect_center_point(&bounds);
|
||||
int16_t radius = bounds.size.w / 2;
|
||||
|
||||
// test robustness of perimeter_horizontal_range_for_circle
|
||||
for (int y = 0; y < bounds.size.h; y++) {
|
||||
GRangeHorizontal h_range = perimeter_for_circle(
|
||||
(GRangeVertical) {.origin_y = y, .size_h = 0}, center, radius);
|
||||
|
||||
// internally we use integer_sqrt, which causes precision loss
|
||||
// so we need to mirror some of the fixed point truncation here
|
||||
int16_t height = 90 - y;
|
||||
int16_t width = sqrt(radius * radius - height * height);
|
||||
int16_t test_origin = 90 - width;
|
||||
|
||||
// Due to integer math and truncation, we need to test +-1
|
||||
cl_assert(BETWEEN(h_range.origin_x, test_origin - 1, test_origin + 1));
|
||||
cl_assert(BETWEEN(h_range.size_w, (width - 1) * 2, (width + 1) * 2));
|
||||
}
|
||||
}
|
||||
|
||||
#define cl_assert_equal_rangehorizontal(r1, r2) \
|
||||
do { \
|
||||
cl_assert_equal_i((r1).origin_x, (r2).origin_x); \
|
||||
cl_assert_equal_i((r1).size_w, (r2).size_w); \
|
||||
} while(0)
|
||||
|
||||
void test_perimeter__perimeter_for_display_rect(void) {
|
||||
GPerimeter p = {
|
||||
.callback = perimeter_for_display_rect,
|
||||
};
|
||||
const GSize ctx_size = GSize(DISP_COLS, DISP_ROWS);
|
||||
GRangeVertical r = {.origin_y = 10, .size_h = 10};
|
||||
|
||||
GRangeHorizontal expected = (GRangeHorizontal){.origin_x = 0, .size_w = DISP_COLS};
|
||||
cl_assert_equal_rangehorizontal(expected, perimeter_for_display_rect(&p, &ctx_size, r, 0));
|
||||
expected = (GRangeHorizontal){.origin_x = 5, .size_w = DISP_COLS - 10};
|
||||
cl_assert_equal_rangehorizontal(expected, perimeter_for_display_rect(&p, &ctx_size, r, 5));
|
||||
cl_assert_equal_i(0, perimeter_for_display_rect(&p, &ctx_size, r, 500).size_w);
|
||||
}
|
||||
|
||||
void test_perimeter__perimeter_for_display_round(void) {
|
||||
GPerimeter p = {
|
||||
.callback = perimeter_for_display_round,
|
||||
};
|
||||
GRangeVertical r = {.origin_y = 10, .size_h = 10};
|
||||
const GSize ctx_size = GSize(DISP_COLS, DISP_ROWS);
|
||||
const GRect disp = GRect(0, 0, DISP_COLS, DISP_ROWS);
|
||||
|
||||
GRangeHorizontal expected =
|
||||
perimeter_for_circle(r, grect_center_point(&disp), grect_shortest_side(disp) / 2);
|
||||
cl_assert_equal_rangehorizontal(expected, perimeter_for_display_round(&p, &ctx_size, r, 0));
|
||||
expected = perimeter_for_circle(r, grect_center_point(&disp), grect_shortest_side(disp) / 2 - 5);
|
||||
cl_assert_equal_rangehorizontal(expected, perimeter_for_display_round(&p, &ctx_size, r, 5));
|
||||
cl_assert_equal_i(0, perimeter_for_display_round(&p, &ctx_size, r, 500).size_w);
|
||||
}
|
||||
|
||||
void test_perimeter__g_perimeter_for_display(void) {
|
||||
GPerimeterCallback expected = PBL_IF_RECT_ELSE(perimeter_for_display_rect,
|
||||
perimeter_for_display_round);
|
||||
cl_assert_equal_p(expected, g_perimeter_for_display->callback);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue