designer2 preview text

This commit is contained in:
nakst 2021-09-30 09:38:15 +01:00
parent ac11b40f19
commit 2669b607ff
2 changed files with 94 additions and 9 deletions

View File

@ -106,15 +106,18 @@ void GlyphCacheFreeEntry() {
}
void RegisterGlyphCacheEntry(GlyphCacheKey key, GlyphCacheEntry *entry) {
// Free space in the glyph cache.
// Do this before adding the new glyph to the cache,
// in case the new glyph doesn't fit in the cache at all.
while (fontManagement.glyphCacheBytes > GLYPH_CACHE_MAX_SIZE) {
GlyphCacheFreeEntry();
}
entry->itemLRU.thisItem = entry;
entry->key = key;
*fontManagement.glyphCache.Put(&key) = entry;
fontManagement.glyphCacheLRU.InsertStart(&entry->itemLRU);
fontManagement.glyphCacheBytes += entry->dataBytes;
while (fontManagement.glyphCacheBytes > GLYPH_CACHE_MAX_SIZE) {
GlyphCacheFreeEntry();
}
}
GlyphCacheEntry *LookupGlyphCacheEntry(GlyphCacheKey key) {
@ -311,6 +314,11 @@ bool FontRenderGlyph(bool mono, GlyphCacheKey key, GlyphCacheEntry *entry) {
xoff = key.font.ft->glyph->bitmap_left;
yoff = -key.font.ft->glyph->bitmap_top;
if ((uint64_t) width * (uint64_t) height * 4 > 100000000) {
// Refuse to output glyphs more than 100MB.
return false;
}
entry->dataBytes = 1 + (width * height + 7) / 8;
output = (uint8_t *) EsHeapAllocate(entry->dataBytes, true);
@ -2395,7 +2403,7 @@ void DrawTextPiece(EsPainter *painter, EsTextPlan *plan, TextPiece *piece, TextL
key.font = plan->font;
GlyphCacheEntry *entry = nullptr;
if (codepoint == 0xFFFFFFFF) {
if (codepoint == 0xFFFFFFFF || key.size > 2000) {
goto nextCharacter;
}

View File

@ -120,7 +120,7 @@ bool EsColorIsLight(uint32_t color) {
struct EsPaintTarget {
void *bits;
uint32_t width, height, stride;
bool fullAlpha, readOnly;
bool fullAlpha, readOnly, fromBitmap, forWindowManager;
};
struct EsPainter {
@ -830,7 +830,7 @@ int InspectorBoundMessage(UIElement *element, UIMessage message, int di, void *d
memcpy(buffer, textbox->string, length);
buffer[length] = 0;
step.property.type = PROP_INT;
step.property.integer = (int32_t) strtol(buffer, nullptr, 0);
step.property.integer = (int32_t) strtol(buffer, nullptr, 10);
InspectorBroadcastStep(step, data);
} else if (data->elementType == INSPECTOR_FLOAT_TEXTBOX) {
UITextbox *textbox = (UITextbox *) element;
@ -1516,6 +1516,16 @@ uint32_t GraphGetColor(Object *object, int depth = 0) {
}
}
uint32_t GraphGetColorFromProperty(Property *property) {
if (!property) {
return 0;
} else if (property->type == PROP_OBJECT) {
return GraphGetColor(ObjectFind(property->object));
} else {
return 0;
}
}
//////////////////////////////////////////////////////////////
void ExportGradientStopArray(Object *object, EsBuffer *data, size_t stopCount) {
@ -1725,6 +1735,28 @@ void CanvasDrawLayer(Object *object, UIRectangle bounds, UIPainter *painter, int
EsBufferWrite(&data, &layer, sizeof(layer));
ExportLayerBox(depth == 0, object, &data);
CanvasDrawLayerFromData(painter, bounds, data);
} else if (object->type == OBJ_LAYER_TEXT) {
#ifdef OS_ESSENCE
EsPaintTarget paintTarget = {};
_EsPainter themePainter = {};
themePainter.target = (_EsPaintTarget *) &paintTarget;
themePainter.clip.l = painter->clip.l;
themePainter.clip.r = painter->clip.r;
themePainter.clip.t = painter->clip.t;
themePainter.clip.b = painter->clip.b;
paintTarget.bits = painter->bits;
paintTarget.width = painter->width;
paintTarget.height = painter->height;
paintTarget.stride = painter->width * 4;
EsTextStyle textStyle = {};
textStyle.font.family = ES_FONT_SANS;
textStyle.font.weight = 5;
textStyle.size = 10;
textStyle.color = GraphGetColorFromProperty(PropertyFindOrInherit(false, object, "color"));
textStyle.blur = GraphGetIntegerFromProperty(PropertyFindOrInherit(false, object, "blur"));
if (textStyle.blur > 10) textStyle.blur = 10;
EsDrawTextSimple((_EsPainter *) &themePainter, ui.instance->window, bounds, "Sample", -1, textStyle, ES_TEXT_H_CENTER | ES_TEXT_V_CENTER);
#endif
} else if (object->type == OBJ_LAYER_GROUP) {
int32_t layerCount = PropertyReadInt32(object, "layers_count");
if (layerCount < 0) layerCount = 0;
@ -1767,6 +1799,49 @@ void CanvasDrawLayer(Object *object, UIRectangle bounds, UIPainter *painter, int
}
}
void CanvasDrawStyle(Object *object, UIRectangle bounds, UIPainter *painter, int depth = 0) {
if (!object || depth == 100) {
return;
}
#ifdef OS_ESSENCE
EsPaintTarget paintTarget = {};
_EsPainter themePainter = {};
themePainter.target = (_EsPaintTarget *) &paintTarget;
themePainter.clip.l = painter->clip.l;
themePainter.clip.r = painter->clip.r;
themePainter.clip.t = painter->clip.t;
themePainter.clip.b = painter->clip.b;
paintTarget.bits = painter->bits;
paintTarget.width = painter->width;
paintTarget.height = painter->height;
paintTarget.stride = painter->width * 4;
if (object->type == OBJ_VAR_TEXT_STYLE) {
EsTextStyle textStyle = {};
textStyle.font.family = GraphGetIntegerFromProperty(PropertyFindOrInherit(false, object, "fontFamily"));
textStyle.font.weight = GraphGetIntegerFromProperty(PropertyFindOrInherit(false, object, "fontWeight"));
textStyle.font.italic = GraphGetIntegerFromProperty(PropertyFindOrInherit(false, object, "isItalic"));
textStyle.size = GraphGetIntegerFromProperty(PropertyFindOrInherit(false, object, "textSize"));
textStyle.color = GraphGetColorFromProperty(PropertyFindOrInherit(false, object, "textColor"));
EsDrawTextSimple((_EsPainter *) &themePainter, ui.instance->window, bounds, "Sample", -1, textStyle, ES_TEXT_H_CENTER | ES_TEXT_V_CENTER);
} else if (object->type == OBJ_VAR_ICON_STYLE) {
EsDrawStandardIcon((_EsPainter *) &themePainter, ES_ICON_GO_NEXT_SYMBOLIC,
GraphGetIntegerFromProperty(PropertyFindOrInherit(false, object, "iconSize")), bounds,
GraphGetColorFromProperty(PropertyFindOrInherit(false, object, "iconColor")));
}
#endif
if (object->type == OBJ_STYLE) {
Property *appearance = PropertyFindOrInherit(false, object, "appearance");
Property *textStyle = PropertyFindOrInherit(false, object, "textStyle");
Property *iconStyle = PropertyFindOrInherit(false, object, "iconStyle");
if (appearance) CanvasDrawLayer(ObjectFind(appearance->object), bounds, painter, depth + 1);
if (textStyle) CanvasDrawStyle(ObjectFind(textStyle->object), bounds, painter, depth + 1);
else if (iconStyle) CanvasDrawStyle(ObjectFind(iconStyle->object), bounds, painter, depth + 1);
}
}
int CanvasMessage(UIElement *element, UIMessage message, int di, void *dp) {
if (message == UI_MSG_PAINT) {
UIPainter *painter = (UIPainter *) dp;
@ -1814,7 +1889,7 @@ int CanvasMessage(UIElement *element, UIMessage message, int di, void *dp) {
char buffer[32];
snprintf(buffer, sizeof(buffer), "%d", value);
UIDrawString(painter, bounds, buffer, -1, 0xFF000000, UI_ALIGN_CENTER, nullptr);
} else if (object->type == OBJ_LAYER_BOX || object->type == OBJ_LAYER_GROUP) {
} else if (object->type == OBJ_LAYER_BOX || object->type == OBJ_LAYER_GROUP || object->type == OBJ_LAYER_TEXT) {
CanvasDrawLayer(object, bounds, painter);
} else if (object->type == OBJ_PAINT_LINEAR_GRADIENT || object->type == OBJ_PAINT_RADIAL_GRADIENT) {
CanvasDrawColorSwatch(object, bounds, painter);
@ -1826,8 +1901,10 @@ int CanvasMessage(UIElement *element, UIMessage message, int di, void *dp) {
snprintf(buffer, sizeof(buffer), "%.8X", color);
UIRectangle area = UI_RECT_4(bounds.l, bounds.r, bounds.t, bounds.t + UIMeasureStringHeight());
UIDrawString(painter, area, buffer, -1, isLight ? 0xFF000000 : 0xFFFFFFFF, UI_ALIGN_CENTER, nullptr);
} else if (object->type == OBJ_VAR_TEXT_STYLE || object->type == OBJ_VAR_ICON_STYLE || object->type == OBJ_STYLE) {
CanvasDrawStyle(object, bounds, painter);
} else {
// TODO Preview for more object types: style, text style, icon style, metrics layer, text layer.
// TODO Preview for the metrics layer. Show the preferred size, insets and gaps?
}
}