mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-08 08:31:13 +00:00
rlottie/api: Added support for rendering without keeping aspect ratio
This commit is contained in:
parent
be24fa00c5
commit
715c8450bf
@ -340,6 +340,7 @@ public:
|
||||
*
|
||||
* @param[in] frameNo Content corresponds to the @p frameNo needs to be drawn
|
||||
* @param[in] surface Surface in which content will be drawn
|
||||
* @param[in] keepAspectRatio whether to keep the aspect ratio while scaling the content.
|
||||
*
|
||||
* @return future that will hold the result when rendering finished.
|
||||
*
|
||||
@ -348,7 +349,7 @@ public:
|
||||
* @see Surface
|
||||
* @internal
|
||||
*/
|
||||
std::future<Surface> render(size_t frameNo, Surface surface);
|
||||
std::future<Surface> render(size_t frameNo, Surface surface, bool keepAspectRatio=true);
|
||||
|
||||
/**
|
||||
* @brief Renders the content to surface synchronously.
|
||||
@ -356,10 +357,11 @@ public:
|
||||
*
|
||||
* @param[in] frameNo Content corresponds to the @p frameNo needs to be drawn
|
||||
* @param[in] surface Surface in which content will be drawn
|
||||
* @param[in] keepAspectRatio whether to keep the aspect ratio while scaling the content.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
void renderSync(size_t frameNo, Surface surface);
|
||||
void renderSync(size_t frameNo, Surface surface, bool keepAspectRatio=true);
|
||||
|
||||
/**
|
||||
* @brief Returns root layer of the composition updated with
|
||||
|
@ -32,20 +32,21 @@ struct RenderTask {
|
||||
AnimationImpl * playerImpl{nullptr};
|
||||
size_t frameNo{0};
|
||||
Surface surface;
|
||||
bool keepAspectRatio{true};
|
||||
};
|
||||
using SharedRenderTask = std::shared_ptr<RenderTask>;
|
||||
|
||||
class AnimationImpl {
|
||||
public:
|
||||
void init(const std::shared_ptr<LOTModel> &model);
|
||||
bool update(size_t frameNo, const VSize &size);
|
||||
bool update(size_t frameNo, const VSize &size, bool keepAspectRatio);
|
||||
VSize size() const { return mModel->size(); }
|
||||
double duration() const { return mModel->duration(); }
|
||||
double frameRate() const { return mModel->frameRate(); }
|
||||
size_t totalFrame() const { return mModel->totalFrame(); }
|
||||
size_t frameAtPos(double pos) const { return mModel->frameAtPos(pos); }
|
||||
Surface render(size_t frameNo, const Surface &surface);
|
||||
std::future<Surface> renderAsync(size_t frameNo, Surface &&surface);
|
||||
Surface render(size_t frameNo, const Surface &surface, bool keepAspectRatio);
|
||||
std::future<Surface> renderAsync(size_t frameNo, Surface &&surface, bool keepAspectRatio);
|
||||
const LOTLayerNode * renderTree(size_t frameNo, const VSize &size);
|
||||
|
||||
const LayerInfoList &layerInfoList() const
|
||||
@ -71,13 +72,13 @@ void AnimationImpl::setValue(const std::string &keypath, LOTVariant &&value)
|
||||
|
||||
const LOTLayerNode *AnimationImpl::renderTree(size_t frameNo, const VSize &size)
|
||||
{
|
||||
if (update(frameNo, size)) {
|
||||
if (update(frameNo, size, true)) {
|
||||
mCompItem->buildRenderTree();
|
||||
}
|
||||
return mCompItem->renderTree();
|
||||
}
|
||||
|
||||
bool AnimationImpl::update(size_t frameNo, const VSize &size)
|
||||
bool AnimationImpl::update(size_t frameNo, const VSize &size, bool keepAspectRatio)
|
||||
{
|
||||
frameNo += mModel->startFrame();
|
||||
|
||||
@ -85,11 +86,10 @@ bool AnimationImpl::update(size_t frameNo, const VSize &size)
|
||||
|
||||
if (frameNo < mModel->startFrame()) frameNo = mModel->startFrame();
|
||||
|
||||
mCompItem->resize(size);
|
||||
return mCompItem->update(int(frameNo));
|
||||
return mCompItem->update(int(frameNo), size, keepAspectRatio);
|
||||
}
|
||||
|
||||
Surface AnimationImpl::render(size_t frameNo, const Surface &surface)
|
||||
Surface AnimationImpl::render(size_t frameNo, const Surface &surface, bool keepAspectRatio)
|
||||
{
|
||||
bool renderInProgress = mRenderInProgress.load();
|
||||
if (renderInProgress) {
|
||||
@ -99,7 +99,7 @@ Surface AnimationImpl::render(size_t frameNo, const Surface &surface)
|
||||
|
||||
mRenderInProgress.store(true);
|
||||
update(frameNo,
|
||||
VSize(int(surface.drawRegionWidth()), int(surface.drawRegionHeight())));
|
||||
VSize(int(surface.drawRegionWidth()), int(surface.drawRegionHeight())), keepAspectRatio);
|
||||
mCompItem->render(surface);
|
||||
mRenderInProgress.store(false);
|
||||
|
||||
@ -149,7 +149,7 @@ class RenderTaskScheduler {
|
||||
if (!success && !_q[i].pop(task)) break;
|
||||
|
||||
auto result =
|
||||
task->playerImpl->render(task->frameNo, task->surface);
|
||||
task->playerImpl->render(task->frameNo, task->surface, task->keepAspectRatio);
|
||||
task->sender.set_value(result);
|
||||
}
|
||||
}
|
||||
@ -211,7 +211,8 @@ public:
|
||||
#endif
|
||||
|
||||
std::future<Surface> AnimationImpl::renderAsync(size_t frameNo,
|
||||
Surface &&surface)
|
||||
Surface &&surface,
|
||||
bool keepAspectRatio)
|
||||
{
|
||||
if (!mTask) {
|
||||
mTask = std::make_shared<RenderTask>();
|
||||
@ -222,6 +223,7 @@ std::future<Surface> AnimationImpl::renderAsync(size_t frameNo,
|
||||
mTask->playerImpl = this;
|
||||
mTask->frameNo = frameNo;
|
||||
mTask->surface = std::move(surface);
|
||||
mTask->keepAspectRatio = keepAspectRatio;
|
||||
|
||||
return RenderTaskScheduler::instance().process(mTask);
|
||||
}
|
||||
@ -300,14 +302,14 @@ const LOTLayerNode *Animation::renderTree(size_t frameNo, size_t width,
|
||||
return d->renderTree(frameNo, VSize(int(width), int(height)));
|
||||
}
|
||||
|
||||
std::future<Surface> Animation::render(size_t frameNo, Surface surface)
|
||||
std::future<Surface> Animation::render(size_t frameNo, Surface surface, bool keepAspectRatio)
|
||||
{
|
||||
return d->renderAsync(frameNo, std::move(surface));
|
||||
return d->renderAsync(frameNo, std::move(surface), keepAspectRatio);
|
||||
}
|
||||
|
||||
void Animation::renderSync(size_t frameNo, Surface surface)
|
||||
void Animation::renderSync(size_t frameNo, Surface surface, bool keepAspectRatio)
|
||||
{
|
||||
d->render(frameNo, surface);
|
||||
d->render(frameNo, surface, keepAspectRatio);
|
||||
}
|
||||
|
||||
const LayerInfoList &Animation::layers() const
|
||||
|
@ -70,7 +70,7 @@ static bool strokeProp(rlottie::Property prop)
|
||||
}
|
||||
|
||||
LOTCompItem::LOTCompItem(LOTModel *model)
|
||||
: mUpdateViewBox(false), mCurFrameNo(-1)
|
||||
: mCurFrameNo(-1)
|
||||
{
|
||||
mCompData = model->mRoot.get();
|
||||
mRootLayer = createLayerItem(mCompData->mRootLayer.get());
|
||||
@ -109,38 +109,36 @@ std::unique_ptr<LOTLayerItem> LOTCompItem::createLayerItem(
|
||||
}
|
||||
}
|
||||
|
||||
void LOTCompItem::resize(const VSize &size)
|
||||
{
|
||||
if (mViewSize == size) return;
|
||||
mViewSize = size;
|
||||
mUpdateViewBox = true;
|
||||
}
|
||||
|
||||
bool LOTCompItem::update(int frameNo)
|
||||
bool LOTCompItem::update(int frameNo, const VSize &size, bool keepAspectRatio)
|
||||
{
|
||||
// check if cached frame is same as requested frame.
|
||||
if (!mUpdateViewBox && (mCurFrameNo == frameNo)) return false;
|
||||
if ((mViewSize == size) &&
|
||||
(mCurFrameNo == frameNo) &&
|
||||
(mKeepAspectRatio == keepAspectRatio)) return false;
|
||||
|
||||
mViewSize = size;
|
||||
mCurFrameNo = frameNo;
|
||||
mKeepAspectRatio = keepAspectRatio;
|
||||
|
||||
/*
|
||||
* if viewbox dosen't scale exactly to the viewport
|
||||
* we scale the viewbox keeping AspectRatioPreserved and then align the
|
||||
* viewbox to the viewport using AlignCenter rule.
|
||||
*/
|
||||
VMatrix m;
|
||||
VSize viewPort = mViewSize;
|
||||
VSize viewBox = mCompData->size();
|
||||
|
||||
float sx = float(viewPort.width()) / viewBox.width();
|
||||
float sy = float(viewPort.height()) / viewBox.height();
|
||||
float scale = std::min(sx, sy);
|
||||
float tx = (viewPort.width() - viewBox.width() * scale) * 0.5f;
|
||||
float ty = (viewPort.height() - viewBox.height() * scale) * 0.5f;
|
||||
|
||||
VMatrix m;
|
||||
m.translate(tx, ty).scale(scale, scale);
|
||||
if (mKeepAspectRatio) {
|
||||
float scale = std::min(sx, sy);
|
||||
float tx = (viewPort.width() - viewBox.width() * scale) * 0.5f;
|
||||
float ty = (viewPort.height() - viewBox.height() * scale) * 0.5f;
|
||||
m.translate(tx, ty).scale(scale, scale);
|
||||
} else {
|
||||
m.scale(sx, sy);
|
||||
}
|
||||
mRootLayer->update(frameNo, m, 1.0);
|
||||
|
||||
mCurFrameNo = frameNo;
|
||||
mUpdateViewBox = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -65,19 +65,18 @@ class LOTCompItem
|
||||
public:
|
||||
explicit LOTCompItem(LOTModel *model);
|
||||
static std::unique_ptr<LOTLayerItem> createLayerItem(LOTLayerData *layerData);
|
||||
bool update(int frameNo);
|
||||
void resize(const VSize &size);
|
||||
bool update(int frameNo, const VSize &size, bool keepAspectRatio);
|
||||
VSize size() const { return mViewSize;}
|
||||
void buildRenderTree();
|
||||
const LOTLayerNode * renderTree()const;
|
||||
bool render(const rlottie::Surface &surface);
|
||||
void setValue(const std::string &keypath, LOTVariant &value);
|
||||
private:
|
||||
VMatrix mScaleMatrix;
|
||||
VSize mViewSize;
|
||||
VMatrix mScaleMatrix;
|
||||
VSize mViewSize;
|
||||
LOTCompositionData *mCompData;
|
||||
std::unique_ptr<LOTLayerItem> mRootLayer;
|
||||
bool mUpdateViewBox;
|
||||
bool mKeepAspectRatio{true};
|
||||
int mCurFrameNo;
|
||||
std::vector<LOTNode *> mRenderList;
|
||||
std::vector<VDrawable *> mDrawableList;
|
||||
|
Loading…
x
Reference in New Issue
Block a user