kit: getslide message + renderSlide/renderNextSlideLayer implementation

Signed-off-by: Marco Cecchetti <marco.cecchetti@collabora.com>
Change-Id: Ib6da153427f244f50787d28f93e58137b95b7bdb
This commit is contained in:
Marco Cecchetti 2024-07-08 10:30:50 +02:00 committed by Szymon Kłos
parent 55601cf74e
commit 1aebb4f40a
4 changed files with 117 additions and 0 deletions

View file

@ -499,6 +499,10 @@ bool ChildSession::_handleInput(const char *buffer, int length)
{
return getStatus();
}
else if (tokens.equals(0, "getslide"))
{
return renderSlide(tokens);
}
else if (tokens.equals(0, "paintwindow"))
{
return renderWindow(tokens);
@ -2189,6 +2193,115 @@ uint64_t hashSubBuffer(unsigned char* pixmap, size_t startX, size_t startY,
}
}
bool ChildSession::renderNextSlideLayer(int width, int height, size_t pixmapDataSize, bool& done)
{
std::vector<unsigned char> pixmap(pixmapDataSize);
bool bIsBitmapLayer = false;
char* msg = nullptr;
done = getLOKitDocument()->renderNextSlideLayer(pixmap.data(), &bIsBitmapLayer, &msg);
std::string jsonMsg(msg);
free(msg);
if (jsonMsg.empty())
return true;
if (!bIsBitmapLayer)
{
std::string response = "slidelayer: " + jsonMsg;
sendTextFrame(response);
return true;
}
uint64_t pixmapHash = hashSubBuffer(pixmap.data(), 0, 0, width, height, width, height) + getViewId();
if (size_t start = jsonMsg.find("%IMAGETYPE%"); start != std::string::npos)
jsonMsg.replace(start, 11, "png");
if (size_t start = jsonMsg.find("%IMAGECHECKSUM%"); start != std::string::npos)
jsonMsg.replace(start, 15, std::to_string(pixmapHash));
std::string response = "slidelayer: " + jsonMsg;
response += "\n";
std::vector<char> output;
output.reserve(response.size() + pixmapDataSize);
output.resize(response.size());
std::memcpy(output.data(), response.data(), response.size());
const auto tileMode = static_cast<LibreOfficeKitTileMode>(getLOKitDocument()->getTileMode());
if (!Png::encodeSubBufferToPNG(pixmap.data(), 0, 0, width, height, width, height, output, tileMode))
{
LOG_ERR("Failed to encode into PNG.");
return false;
}
LOG_TRC("Sending response (" << output.size() << " bytes) for: " << std::string(output.data(), response.size() - 1));
sendBinaryFrame(output.data(), output.size());
return true;
}
bool ChildSession::renderSlide(const StringVector& tokens)
{
int part = -1;
std::string partString;
if (tokens.size() > 1 && getTokenString(tokens[1], "part", partString))
{
part = std::stoi(partString);
}
int suggestedWidth = -1;
std::string widthString;
if (tokens.size() > 2 && getTokenString(tokens[2], "width", widthString))
{
suggestedWidth = std::stoi(widthString);
}
int suggestedHeight = -1;
std::string heightString;
if (tokens.size() > 3 && getTokenString(tokens[3], "height", heightString))
{
suggestedHeight = std::stoi(heightString);
}
if (part < 0 || suggestedWidth < 0 || suggestedHeight < 0)
return false;
bool renderBackground = true;
std::string renderBackgroundString;
if (tokens.size() > 4 && getTokenString(tokens[4], "renderBackground", renderBackgroundString))
{
renderBackground = std::stoi(renderBackgroundString) > 0;
}
bool renderMasterPage = true;
std::string renderMasterPageString;
if (tokens.size() > 5 && getTokenString(tokens[5], "renderMasterPage", renderMasterPageString))
{
renderMasterPage = std::stoi(renderMasterPageString) > 0;
}
unsigned int bufferWidth = suggestedWidth;
unsigned int bufferHeight = suggestedHeight;
bool success = getLOKitDocument()->createSlideRenderer(part,
&bufferWidth, &bufferHeight,
renderBackground, renderMasterPage);
if (!success)
return false;
const int width = bufferWidth;
const int height = bufferHeight;
const size_t pixmapDataSize = 4 * bufferWidth * bufferHeight;
bool done = false;
while (!done)
{
success = renderNextSlideLayer(width, height, pixmapDataSize, done);
if (!success)
break;
}
getLOKitDocument()->postSlideshowCleanup();
sendTextFrame("sliderenderingcomplete");
return success;
}
bool ChildSession::renderWindow(const StringVector& tokens)
{
const unsigned winId = (tokens.size() > 1 ? std::stoul(tokens[1]) : 0);

View file

@ -154,6 +154,8 @@ private:
bool unoCommand(const StringVector& tokens);
bool selectText(const StringVector& tokens, const LokEventTargetEnum target);
bool selectGraphic(const StringVector& tokens);
bool renderNextSlideLayer(int width, int height, size_t pixmapDataSize, bool& done);
bool renderSlide(const StringVector& tokens);
bool renderWindow(const StringVector& tokens);
bool resizeWindow(const StringVector& tokens);
bool resetSelection(const StringVector& tokens);

View file

@ -128,6 +128,7 @@ void KitWebSocketHandler::handleMessage(const std::vector<char>& data)
}
}
else if (tokens.equals(0, "tile") || tokens.equals(0, "tilecombine") ||
tokens.equals(0, "getslide") ||
tokens.equals(0, "paintwindow") || tokens.equals(0, "resizewindow") ||
COOLProtocol::getFirstToken(tokens[0], '-') == "child")
{

View file

@ -1192,6 +1192,7 @@ bool ClientSession::_handleInput(const char *buffer, int length)
tokens.equals(0, "urp") ||
tokens.equals(0, "useractive") ||
tokens.equals(0, "userinactive") ||
tokens.equals(0, "getslide") ||
tokens.equals(0, "paintwindow") ||
tokens.equals(0, "windowcommand") ||
tokens.equals(0, "asksignaturestatus") ||