mirror of
https://github.com/google/pebble.git
synced 2025-05-31 15:33:11 +00:00
142 lines
4.3 KiB
C
142 lines
4.3 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 "gdraw_command_image.h"
|
|
#include "gdraw_command_private.h"
|
|
|
|
#include "applib/applib_malloc.auto.h"
|
|
#include "applib/applib_resource_private.h"
|
|
#include "syscall/syscall.h"
|
|
|
|
GDrawCommandImage *gdraw_command_image_create_with_resource(uint32_t resource_id) {
|
|
ResAppNum app_num = sys_get_current_resource_num();
|
|
|
|
return gdraw_command_image_create_with_resource_system(app_num, resource_id);
|
|
}
|
|
|
|
GDrawCommandImage *gdraw_command_image_create_with_resource_system(ResAppNum app_num,
|
|
uint32_t resource_id) {
|
|
uint32_t data_size;
|
|
if (!gdraw_command_resource_is_valid(app_num, resource_id, PDCI_SIGNATURE, &data_size)) {
|
|
return NULL;
|
|
}
|
|
|
|
GDrawCommandImage *draw_command_image = applib_resource_mmap_or_load(app_num, resource_id,
|
|
PDCI_DATA_OFFSET, data_size,
|
|
false);
|
|
|
|
// Validate the loaded command image
|
|
if (!gdraw_command_image_validate(draw_command_image, data_size)) {
|
|
gdraw_command_image_destroy(draw_command_image);
|
|
return NULL;
|
|
}
|
|
|
|
return draw_command_image;
|
|
}
|
|
|
|
bool gdraw_command_image_copy(void *buffer, size_t buffer_length, GDrawCommandImage *src) {
|
|
size_t src_size = gdraw_command_image_get_data_size(src);
|
|
if (buffer_length < src_size) {
|
|
return false;
|
|
}
|
|
|
|
memcpy(buffer, src, src_size);
|
|
return true;
|
|
}
|
|
|
|
GDrawCommandImage *gdraw_command_image_clone(GDrawCommandImage *image) {
|
|
if (!image) {
|
|
return NULL;
|
|
}
|
|
|
|
// potentially extracting into a generic task_ptrdup(void *, size_t)
|
|
size_t size = gdraw_command_image_get_data_size(image);
|
|
GDrawCommandImage *result = applib_malloc(size);
|
|
if (result) {
|
|
memcpy(result, image, size);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
void gdraw_command_image_destroy(GDrawCommandImage *image) {
|
|
applib_resource_munmap_or_free(image);
|
|
}
|
|
|
|
bool gdraw_command_image_validate(GDrawCommandImage *image, size_t size) {
|
|
if (!image ||
|
|
(size < sizeof(GDrawCommandImage)) ||
|
|
(image->version > GDRAW_COMMAND_VERSION) ||
|
|
!gdraw_command_list_validate(&image->command_list, size - (sizeof(GDrawCommandImage) -
|
|
sizeof(GDrawCommandList)))) {
|
|
return false;
|
|
}
|
|
uint8_t *end = (uint8_t *)image + size;
|
|
|
|
return (end == gdraw_command_list_iterate_private(&image->command_list, NULL, NULL));
|
|
}
|
|
|
|
void gdraw_command_image_draw(GContext *ctx, GDrawCommandImage *image, GPoint offset) {
|
|
gdraw_command_image_draw_processed(ctx, image, offset, NULL);
|
|
}
|
|
|
|
void gdraw_command_image_draw_processed(GContext *ctx, GDrawCommandImage *image, GPoint offset,
|
|
GDrawCommandProcessor *processor) {
|
|
if (!ctx || !image) {
|
|
return;
|
|
}
|
|
|
|
// Offset graphics context drawing box origin by specified amount
|
|
graphics_context_move_draw_box(ctx, offset);
|
|
|
|
gdraw_command_list_draw_processed(ctx, &image->command_list, processor);
|
|
|
|
// Offset graphics context drawing box back to previous origin
|
|
graphics_context_move_draw_box(ctx, GPoint(-offset.x, -offset.y));
|
|
}
|
|
|
|
size_t gdraw_command_image_get_data_size(GDrawCommandImage *image) {
|
|
if (!image) {
|
|
return 0;
|
|
}
|
|
|
|
return sizeof(GDrawCommandImage) - sizeof(GDrawCommandList)
|
|
+ gdraw_command_list_get_data_size(&image->command_list);
|
|
}
|
|
|
|
GSize gdraw_command_image_get_bounds_size(GDrawCommandImage *image) {
|
|
if (!image) {
|
|
return GSizeZero;
|
|
}
|
|
|
|
return image->size;
|
|
}
|
|
|
|
void gdraw_command_image_set_bounds_size(GDrawCommandImage *image, GSize size) {
|
|
if (!image) {
|
|
return;
|
|
}
|
|
|
|
image->size = size;
|
|
}
|
|
|
|
GDrawCommandList *gdraw_command_image_get_command_list(GDrawCommandImage *image) {
|
|
if (!image) {
|
|
return NULL;
|
|
}
|
|
|
|
return &image->command_list;
|
|
}
|