script console: image detection; text display: don't recreate text plan on resize if not word wrapping

This commit is contained in:
nakst 2022-02-07 09:00:42 +00:00
parent 4f028a18b1
commit dab1cf3efa
2 changed files with 41 additions and 16 deletions

View File

@ -1,8 +1,6 @@
#define ES_INSTANCE_TYPE Instance
#include <essence.h>
// TODO Resizing the window after calling DirectoryEnumerateChildrenRecursively() is slow.
// TODO UTF-8 validation of outputted strings.
// TODO Check for heap allocation leaks.
struct Instance : EsInstance {
@ -633,8 +631,21 @@ void AddREPLResult(ExecutionContext *context, EsElement *parent, Node *type, Val
const char *valueText;
size_t valueBytes;
ScriptHeapEntryToString(context, entry, &valueText, &valueBytes);
char *buffer = EsStringAllocateAndFormat(&bytes, "\u201C%s\u201D", valueBytes, valueText);
EsTextDisplayCreate(parent, ES_CELL_H_FILL, &styleOutputData, buffer, bytes);
uint64_t pngSignature = 0x0A1A0A0D474E5089;
uint32_t jpgSignature = 0xE0FFD8FF;
if ((valueBytes > sizeof(pngSignature) && 0 == EsMemoryCompare(&pngSignature, valueText, sizeof(pngSignature)))
|| (valueBytes > sizeof(jpgSignature) && 0 == EsMemoryCompare(&jpgSignature, valueText, sizeof(jpgSignature)))) {
EsImageDisplay *display = EsImageDisplayCreate(parent, ES_CELL_H_FILL);
EsImageDisplayLoadFromMemory(display, valueText, valueBytes);
} else if (EsUTF8IsValid(valueText, valueBytes)) {
char *buffer = EsStringAllocateAndFormat(&bytes, "\u201C%s\u201D", valueBytes, valueText);
EsTextDisplayCreate(parent, ES_CELL_H_FILL, &styleOutputData, buffer, bytes);
EsHeapFree(buffer);
} else {
EsTextDisplayCreate(parent, ES_CELL_H_FILL, &styleOutputParagraphItalic, EsLiteral("Binary data string.\n"));
}
} else if (type->type == T_LIST && type->firstChild->type == T_STRUCT) {
EsAssert(context->heapEntriesAllocated > (uint64_t) value.i);
HeapEntry *listEntry = &context->heap[value.i];
@ -803,10 +814,17 @@ void AddOutput(Instance *instance, const char *text, size_t textBytes) {
for (uintptr_t i = 0; i < textBytes; i++) {
if (text[i] == '\n') {
EsMessageMutexAcquire();
EsTextDisplayCreate(instance->outputPanel, ES_CELL_H_FILL, &styleOutputParagraph,
instance->outputLineBuffer, instance->outputLineBufferBytes);
EsMessageMutexRelease();
if (EsUTF8IsValid(instance->outputLineBuffer, instance->outputLineBufferBytes)) {
EsMessageMutexAcquire();
EsTextDisplayCreate(instance->outputPanel, ES_CELL_H_FILL, &styleOutputParagraph,
instance->outputLineBuffer, instance->outputLineBufferBytes);
EsMessageMutexRelease();
} else {
EsMessageMutexAcquire();
EsTextDisplayCreate(instance->outputPanel, ES_CELL_H_FILL, &styleOutputParagraphItalic,
EsLiteral("Encoding error.\n"));
EsMessageMutexRelease();
}
instance->outputLineBufferBytes = 0;
} else {
if (instance->outputLineBufferBytes == instance->outputLineBufferAllocated) {

View File

@ -4041,15 +4041,22 @@ int ProcessTextDisplayMessage(EsElement *element, EsMessage *message) {
}
} else if (message->type == ES_MSG_GET_WIDTH || message->type == ES_MSG_GET_HEIGHT) {
if (!display->measurementCache.Get(message, &display->state)) {
if (display->plan) EsTextPlanDestroy(display->plan);
display->properties.flags = display->style->textAlign | ((display->flags & ES_TEXT_DISPLAY_PREFORMATTED) ? 0 : ES_TEXT_PLAN_TRIM_SPACES);
EsRectangle insets = EsElementGetInsets(element);
display->planWidth = message->type == ES_MSG_GET_HEIGHT && message->measure.width
? (message->measure.width - insets.l - insets.r) : 0;
display->planHeight = 0;
display->plan = EsTextPlanCreate(element, &display->properties,
ES_RECT_4(0, display->planWidth, 0, 0),
display->contents, display->textRuns, display->textRunCount);
if ((~display->style->textAlign & ES_TEXT_WRAP) && display->plan) {
// The text is not wrapped, so the input bounds cannot change the measured size.
// Therefore there is no need to recreate the plan.
// TODO Double-check that this is correct.
} else {
if (display->plan) EsTextPlanDestroy(display->plan);
display->properties.flags = display->style->textAlign | ((display->flags & ES_TEXT_DISPLAY_PREFORMATTED) ? 0 : ES_TEXT_PLAN_TRIM_SPACES);
display->planWidth = message->type == ES_MSG_GET_HEIGHT && message->measure.width
? (message->measure.width - insets.l - insets.r) : 0;
display->planHeight = 0;
display->plan = EsTextPlanCreate(element, &display->properties,
ES_RECT_4(0, display->planWidth, 0, 0),
display->contents, display->textRuns, display->textRunCount);
}
if (!display->plan) {
message->measure.width = message->measure.height = 0;