Resize text box when more space is needed (more text or bigger font)

This commit is contained in:
David Capello 2024-08-27 16:01:32 -03:00
parent 49afc0dd52
commit d3a55867c2
3 changed files with 81 additions and 30 deletions

View File

@ -60,25 +60,7 @@ public:
setPersistSelection(true);
// TODO move this opacity() to Site class
int t, opacity = (site.layer()->isImage() ?
static_cast<LayerImage*>(site.layer())->opacity(): 255);
Cel* cel = site.cel();
if (cel) opacity = MUL_UN8(opacity, cel->opacity(), t);
m_extraCel->create(
site.tilemapMode(),
site.sprite(),
bounds,
bounds.size(),
site.frame(),
255);
m_extraCel->setType(render::ExtraType::PATCH);
m_extraCel->setBlendMode(site.layer()->isImage() ?
static_cast<LayerImage*>(site.layer())->blendMode():
doc::BlendMode::NORMAL);
createExtraCel(site, bounds);
renderExtraCelBase();
FontInfo fontInfo = App::instance()->contextBar()->fontInfo();
@ -100,12 +82,36 @@ public:
}
void setExtraCelBounds(const gfx::Rect& bounds) {
m_extraCel->cel()->setBounds(bounds);
if (bounds.w != m_extraCel->image()->width() ||
bounds.h != m_extraCel->image()->height()) {
createExtraCel(m_editor->getSite(), bounds);
}
else {
m_extraCel->cel()->setBounds(bounds);
}
renderExtraCelBase();
renderExtraCelText(true);
}
obs::signal<void(const gfx::Size&)> NewRequiredBounds;
private:
void createExtraCel(const Site& site,
const gfx::Rect& bounds) {
m_extraCel->create(
site.tilemapMode(),
site.sprite(),
bounds,
bounds.size(),
site.frame(),
255);
m_extraCel->setType(render::ExtraType::PATCH);
m_extraCel->setBlendMode(site.layer()->isImage() ?
static_cast<LayerImage*>(site.layer())->blendMode():
doc::BlendMode::NORMAL);
}
bool onProcessMessage(Message* msg) override {
switch (msg->type()) {
case kMouseDownMessage:
@ -132,6 +138,26 @@ private:
setBgColor(gfx::ColorNone);
}
void onSetText() override {
Entry::onSetText();
onNewTextBlob();
}
void onSetFont() override {
Entry::onSetFont();
onNewTextBlob();
}
void onNewTextBlob() {
text::TextBlobRef blob = textBlob();
if (!blob)
return;
// Notify that we could make the text editor bigger to show this
// text blob.
NewRequiredBounds(get_text_blob_required_size(blob));
}
void onPaint(PaintEvent& ev) override {
Graphics* g = ev.graphics();
@ -256,6 +282,16 @@ WritingTextState::WritingTextState(Editor* editor,
App::instance()->contextBar()->FontChange.connect(
&WritingTextState::onFontChange, this);
m_entry->NewRequiredBounds.connect([this](const gfx::Size& blobSize) {
if (m_bounds.w < blobSize.w ||
m_bounds.h < blobSize.h) {
m_bounds.w = std::max(m_bounds.w, blobSize.w);
m_bounds.h = std::max(m_bounds.h, blobSize.h);
m_entry->setExtraCelBounds(m_bounds);
m_entry->setBounds(calcEntryBounds());
}
});
onEditorResize(editor);
}

View File

@ -116,6 +116,24 @@ text::TextBlobRef create_text_blob(
return text::TextBlob::MakeWithShaper(fontMgr, font, text);
}
gfx::Size get_text_blob_required_size(
const text::TextBlobRef& blob)
{
ASSERT(blob != nullptr);
gfx::RectF bounds(0, 0, 1, 1);
blob->visitRuns([&bounds](text::TextBlob::RunInfo& run) {
for (int i=0; i<run.glyphCount; ++i) {
bounds |= run.getGlyphBounds(i);
bounds |= gfx::RectF(0, 0, 1, run.font->metrics(nullptr));
}
});
if (bounds.w < 1) bounds.w = 1;
if (bounds.h < 1) bounds.h = 1;
return gfx::Size(std::ceil(bounds.w),
std::ceil(bounds.h));
}
doc::ImageRef render_text_blob(
const text::TextBlobRef& blob,
gfx::Color color)
@ -127,18 +145,10 @@ doc::ImageRef render_text_blob(
paint.style(os::Paint::Fill);
paint.color(color);
gfx::RectF bounds(0, 0, 1, 1);
blob->visitRuns([&bounds](text::TextBlob::RunInfo& run){
for (int i=0; i<run.glyphCount; ++i) {
bounds |= run.getGlyphBounds(i);
bounds |= gfx::RectF(0, 0, 1, run.font->metrics(nullptr));
}
});
if (bounds.w < 1) bounds.w = 1;
if (bounds.h < 1) bounds.h = 1;
gfx::Size blobSize = get_text_blob_required_size(blob);
doc::ImageRef image(
doc::Image::create(doc::IMAGE_RGB, bounds.w, bounds.h));
doc::Image::create(doc::IMAGE_RGB, blobSize.w, blobSize.h));
#ifdef LAF_SKIA
sk_sp<SkSurface> skSurface = wrap_docimage_in_sksurface(image.get());

View File

@ -28,6 +28,11 @@ namespace app {
const FontInfo& fontInfo,
const std::string& text);
// Returns the exact bounds that are required to draw this TextBlob,
// i.e. the image size that will be required in render_text_blob().
gfx::Size get_text_blob_required_size(
const text::TextBlobRef& blob);
doc::ImageRef render_text_blob(
const text::TextBlobRef& blob,
gfx::Color color);