blob: 2a6af9c006b66e989a6cfd79ab7470f0b4828e38 [file] [log] [blame]
#include "SkData.h"
#include "SkImage.h"
#include "SkStream.h"
#include "SkSurface.h"
#include "rive/file.hpp"
#include "rive/math/aabb.hpp"
#include "skia_factory.hpp"
#include "skia_renderer.hpp"
#include <cstdio>
#include <stdio.h>
#include <string>
#include <iostream>
#include <sstream>
std::string getFileName(char* path)
{
std::string str(path);
const size_t from = str.find_last_of("\\/");
const size_t to = str.find_last_of(".");
return str.substr(from + 1, to - from - 1);
}
const int DEFAULT_SIZE = 256;
int getArg(char* arg)
{
std::istringstream ss(arg);
int x;
if (!(ss >> x))
{
std::cerr << "Invalid number: " << arg << '\n';
}
else if (!ss.eof())
{
std::cerr << "Trailing chars after number: " << arg << '\n';
}
return x == 0 ? DEFAULT_SIZE : x;
}
int main(int argc, char* argv[])
{
rive::SkiaFactory factory;
if (argc < 2)
{
fprintf(stderr, "must pass source file");
return 1;
}
FILE* fp = fopen(argv[1], "rb");
const char* outPath;
std::string filename;
std::string fullName;
if (argc > 2)
{
outPath = argv[2];
}
else
{
filename = getFileName(argv[1]);
fullName = filename + ".png";
outPath = fullName.c_str();
}
int width = DEFAULT_SIZE, height = DEFAULT_SIZE;
if (argc == 5)
{
width = getArg(argv[3]);
height = getArg(argv[4]);
}
if (fp == nullptr)
{
fprintf(stderr, "Failed to open rive file.\n");
return 1;
}
fseek(fp, 0, SEEK_END);
auto length = ftell(fp);
fseek(fp, 0, SEEK_SET);
std::vector<uint8_t> bytes(length);
if (fread(bytes.data(), 1, length, fp) != length)
{
fprintf(stderr, "Failed to read rive file.\n");
fclose(fp);
return 1;
}
fclose(fp);
auto file = rive::File::import(bytes, &factory);
if (!file)
{
fprintf(stderr, "Failed to read rive file.\n");
return 1;
}
auto artboard = file->artboardDefault();
artboard->advance(0.0f);
sk_sp<SkSurface> rasterSurface = SkSurface::MakeRasterN32Premul(width, height);
SkCanvas* rasterCanvas = rasterSurface->getCanvas();
rive::SkiaRenderer renderer(rasterCanvas);
renderer.save();
renderer.align(rive::Fit::cover,
rive::Alignment::center,
rive::AABB(0, 0, width, height),
artboard->bounds());
artboard->draw(&renderer);
renderer.restore();
sk_sp<SkImage> img(rasterSurface->makeImageSnapshot());
if (!img)
{
return 1;
}
sk_sp<SkData> png(img->encodeToData());
if (!png)
{
return 1;
}
SkFILEWStream out(outPath);
(void)out.write(png->data(), png->size());
return 0;
}