Add support Images in nativeEditors

This commit is contained in:
Oleg.Korshul
2024-10-26 15:06:09 +03:00
parent cd1bb3b658
commit a84c8cc471
9 changed files with 254 additions and 60 deletions

View File

@ -1,7 +1,94 @@
#include "../graphics.h"
CGraphicsAppImage::CGraphicsAppImage(){}
CGraphicsAppImage::~CGraphicsAppImage(){}
// APPLICATION INFO
class CGraphicsAppImage_private
{
public:
NSFonts::IApplicationFonts* m_pFonts;
std::wstring m_sFontsDirectory;
std::wstring m_sImagesDirectory;
std::wstring m_sThemesDirectory;
bool m_bIsRgba;
CGraphicsAppImage_private()
{
m_pFonts = NULL;
m_sFontsDirectory = L"";
m_sImagesDirectory = L"";
m_sThemesDirectory = L"";
m_bIsRgba = false;
}
~CGraphicsAppImage_private()
{
RELEASEINTERFACE(m_pFonts);
}
};
CGraphicsAppImage::CGraphicsAppImage()
{
m_internal = new CGraphicsAppImage_private();
}
CGraphicsAppImage::~CGraphicsAppImage()
{
delete m_internal;
}
void CGraphicsAppImage::SetFontsDirectory(const std::wstring& dir)
{
m_internal->m_sFontsDirectory = dir;
}
std::wstring CGraphicsAppImage::GetFontsDirectory()
{
return m_internal->m_sFontsDirectory;
}
void CGraphicsAppImage::SetImagesDirectory(const std::wstring& dir)
{
m_internal->m_sImagesDirectory = dir;
}
std::wstring CGraphicsAppImage::GetImagesDirectory()
{
return m_internal->m_sImagesDirectory;
}
void CGraphicsAppImage::SetThemesDirectory(const std::wstring& dir)
{
m_internal->m_sThemesDirectory = dir;
}
std::wstring CGraphicsAppImage::GetThemesDirectory()
{
return m_internal->m_sThemesDirectory;
}
void CGraphicsAppImage::SetFonts(NSFonts::IApplicationFonts* fonts)
{
m_internal->m_pFonts = fonts;
ADDREFINTERFACE(fonts);
}
NSFonts::IApplicationFonts* CGraphicsAppImage::GetFonts()
{
return m_internal->m_pFonts;
}
void CGraphicsAppImage::SetRgba(const bool& isRgba)
{
m_internal->m_bIsRgba = isRgba;
}
bool CGraphicsAppImage::GetRgba()
{
return m_internal->m_bIsRgba;
}
unsigned char* CGraphicsAppImage::GetBits(int& w, int& h)
{
return NULL;
}
unsigned char* CGraphicsAppImage::AllocBits(const int& w, const int& h)
{
return new unsigned char[4 * w * h];
}
// APPLICATION INFO END
CGraphicsEmbed::CGraphicsEmbed() : m_pInternal(new NSGraphics::CGraphics())
{
@ -11,22 +98,31 @@ CGraphicsEmbed::~CGraphicsEmbed()
RELEASEOBJECT(m_pInternal);
}
CGraphicsAppImage* CGraphicsEmbed::GetAppImage()
{
return m_pInternal->m_pAppImage;
}
void CGraphicsEmbed::SetAppImage(CGraphicsAppImage* appImage)
{
m_pInternal->m_pAppImage = appImage;
}
void CGraphicsEmbed::ExternalizeImage()
{
m_pInternal->m_oFrame.put_Data(NULL);
}
JSSmart<CJSValue> CGraphicsEmbed::create(JSSmart<CJSValue> Native, JSSmart<CJSValue> width_px, JSSmart<CJSValue> height_px, JSSmart<CJSValue> width_mm, JSSmart<CJSValue> height_mm)
{
NSNativeControl::CNativeControl* pControl = NULL;
if (!Native->isNull())
{
pControl = (NSNativeControl::CNativeControl*)Native->toObject()->getNative()->getObject();
m_pInternal->init(pControl, width_px->toDouble(), height_px->toDouble(), width_mm->toDouble(), height_mm->toDouble());
if (m_pInternal->m_pAppImage)
delete m_pInternal->m_pAppImage;
m_pInternal->m_pAppImage = new CGraphicsAppImage();
m_pInternal->m_pAppImage->SetFontsDirectory(pControl->m_strFontsDirectory);
m_pInternal->m_pAppImage->SetImagesDirectory(pControl->m_strImagesDirectory);
}
m_pInternal->init(width_px->toDouble(), height_px->toDouble(), width_mm->toDouble(), height_mm->toDouble());
return NULL;
}
JSSmart<CJSValue> CGraphicsEmbed::Destroy()

View File

@ -4,20 +4,33 @@
#include "../../graphics/pro/Fonts.h"
#include "../js_internal/js_base.h"
class CGraphicsAppImage_private;
class JS_DECL CGraphicsAppImage
{
public:
CGraphicsAppImage();
virtual ~CGraphicsAppImage();
public:
virtual std::wstring GetFontsDirectory() = 0;
virtual NSFonts::IApplicationFonts* GetFonts() = 0;
void SetFontsDirectory(const std::wstring& dir);
std::wstring GetFontsDirectory();
virtual std::wstring GetImagesDirectory() = 0;
virtual std::wstring GetThemesDirectory() = 0;
void SetImagesDirectory(const std::wstring& dir);
std::wstring GetImagesDirectory();
virtual unsigned char* AllocImage(const int& w, const int& h) = 0;
virtual bool IsRgba() = 0;
void SetThemesDirectory(const std::wstring& dir);
std::wstring GetThemesDirectory();
void SetFonts(NSFonts::IApplicationFonts* fonts);
NSFonts::IApplicationFonts* GetFonts();
void SetRgba(const bool& isRgba);
bool GetRgba();
virtual unsigned char* GetBits(int& w, int& h);
virtual unsigned char* AllocBits(const int& w, const int& h);
private:
CGraphicsAppImage_private* m_internal;
};
namespace NSGraphics { class CGraphics; }
@ -34,8 +47,8 @@ public:
virtual void* getObject() override { return (void*)m_pInternal; }
CGraphicsAppImage* GetAppImage();
void SetAppImage(CGraphicsAppImage* appImage);
void ExternalizeImage();
public:
JSSmart<CJSValue> create(JSSmart<CJSValue> Native, JSSmart<CJSValue> width_px, JSSmart<CJSValue> height_px, JSSmart<CJSValue> width_mm, JSSmart<CJSValue> height_mm);

View File

@ -12,37 +12,28 @@
namespace NSGraphics
{
void CGraphics::init(NSNativeControl::CNativeControl* oNative, double width_px, double height_px, double width_mm, double height_mm)
void CGraphics::init(double width_px, double height_px, double width_mm, double height_mm)
{
NSFonts::IFontManager* pManager = NULL;
if (!m_pAppImage)
return;
if (NULL != oNative)
if (NULL == m_pAppImage->GetFonts())
{
m_sApplicationImagesDirectory = oNative->m_strImagesDirectory;
m_sApplicationFontsDirectory = oNative->m_strFontsDirectory;
}
else if (m_pAppImage)
{
m_sApplicationImagesDirectory = m_pAppImage->GetImagesDirectory();
m_sApplicationThemesDirectory = m_pAppImage->GetThemesDirectory();
m_pApplicationFonts = m_pAppImage->GetFonts();
if (m_pApplicationFonts)
{
m_pApplicationFonts->AddRef();
pManager = m_pApplicationFonts->GenerateFontManager();
}
NSFonts::IApplicationFonts* pFonts = NSFonts::NSApplication::Create();
std::wstring sFontsDir = m_pAppImage->GetFontsDirectory();
pFonts->InitializeFromFolder(sFontsDir.empty() ? NSFile::GetProcessDirectory() : sFontsDir);
m_pAppImage->SetFonts(pFonts);
RELEASEINTERFACE(pFonts);
}
if (!pManager)
{
m_pApplicationFonts = NSFonts::NSApplication::Create();
m_pApplicationFonts->InitializeFromFolder(m_sApplicationFontsDirectory.empty() ? NSFile::GetProcessDirectory() : m_sApplicationFontsDirectory);
pManager = m_pApplicationFonts->GenerateFontManager();
}
NSFonts::IFontManager* pManager = m_pAppImage->GetFonts()->GenerateFontManager();
#ifdef _DEBUG
std::wcout << L"init "<< m_sApplicationImagesDirectory << L" " << m_sApplicationFontsDirectory << L" " << width_px << L" " << height_px << L" " << width_mm << L" " << height_mm << std::endl;
std::wcout << L"init "<<
m_pAppImage->GetImagesDirectory() << L" " <<
m_pAppImage->GetFontsDirectory() << L" " <<
width_px << L" " << height_px << L" " <<
width_mm << L" " << height_mm << std::endl;
#endif
m_pRenderer = NSGraphics::Create();
@ -64,7 +55,19 @@ namespace NSGraphics
if (nRasterH < 1) nRasterH = 0;
}
BYTE* pData = m_pAppImage ? m_pAppImage->AllocImage(nRasterW, nRasterH) : new BYTE[4 * nRasterW * nRasterH];
int nExistW = 0;
int nExistH = 0;
BYTE* pData = m_pAppImage->GetBits(nExistW, nExistH);
if (pData != NULL)
{
nRasterW = nExistW;
nRasterH = nExistH;
}
else
{
pData = m_pAppImage->AllocBits(nRasterW, nRasterH);
}
unsigned int back = 0xffffff;
unsigned int* pData32 = (unsigned int*)pData;
unsigned int* pData32End = pData32 + nRasterW * nRasterH;
@ -77,7 +80,7 @@ namespace NSGraphics
m_oFrame.put_Stride(4 * nRasterW);
m_pRenderer->CreateFromBgraFrame(&m_oFrame);
m_pRenderer->SetSwapRGB(m_pAppImage ? m_pAppImage->IsRgba() : false);
m_pRenderer->SetSwapRGB(m_pAppImage->GetRgba());
m_pRenderer->put_Width(width_mm);
m_pRenderer->put_Height(height_mm);
@ -265,7 +268,7 @@ namespace NSGraphics
#ifdef _DEBUG
std::cout << "save " << std::endl;
#endif
m_oFrame.SaveFile(m_sApplicationImagesDirectory + L"/img.png", _CXIMAGE_FORMAT_PNG);
m_oFrame.SaveFile(m_pAppImage->GetImagesDirectory() + L"/img.png", _CXIMAGE_FORMAT_PNG);
}
void CGraphics::restore()
{
@ -306,7 +309,7 @@ namespace NSGraphics
}
void CGraphics::drawImage(const std::wstring& img, double x, double y, double w, double h, BYTE alpha)
{
std::wstring strImage = (0 == img.find(L"theme") ? m_sApplicationThemesDirectory : m_sApplicationImagesDirectory) + L'/' + img;
std::wstring strImage = (0 == img.find(L"theme") ? m_pAppImage->GetThemesDirectory() : m_pAppImage->GetImagesDirectory()) + L'/' + img;
#ifdef _DEBUG
std::wcout << L"drawImage " << strImage << L" " << x << " " << y << L" " << w << L" " << h << L" " << alpha << std::endl;
#endif
@ -1200,7 +1203,7 @@ namespace NSGraphics
{
if (src.find(L"data:") == 0)
{
std::wstring strImage = m_sApplicationImagesDirectory + L"/texture.png";
std::wstring strImage = m_pAppImage->GetImagesDirectory() + L"/texture.png";
bool bIsOnlyOfficeHatch = false;
if(src.find(L"onlyoffice_hatch") != std::wstring::npos)
bIsOnlyOfficeHatch = true;
@ -1243,7 +1246,7 @@ namespace NSGraphics
}
else
{
std::wstring strImage = (0 == src.find(L"theme") ? m_sApplicationThemesDirectory : m_sApplicationImagesDirectory) + L'/' + src;
std::wstring strImage = (0 == src.find(L"theme") ? m_pAppImage->GetThemesDirectory() : m_pAppImage->GetImagesDirectory()) + L'/' + src;
std::wstring sName = strImage.substr(0, strImage.rfind(L'.') + 1);
std::wstring sExt = src.substr(src.rfind(L'.') + 1);
if (sExt == L"svg")

View File

@ -114,11 +114,6 @@ namespace NSGraphics
class CGraphics
{
public:
std::wstring m_sApplicationFontsDirectory;
std::wstring m_sApplicationImagesDirectory;
std::wstring m_sApplicationThemesDirectory;
public:
CGraphicsAppImage* m_pAppImage;
CBgraFrame m_oFrame;
@ -138,9 +133,13 @@ namespace NSGraphics
Destroy();
}
void init(NSNativeControl::CNativeControl* oNative, double width_px, double height_px, double width_mm, double height_mm);
void init(double width_px, double height_px, double width_mm, double height_mm);
void Destroy()
{
int w, h;
if (m_pAppImage->GetBits(w, h))
m_oFrame.put_Data(NULL);
RELEASEINTERFACE(m_pRenderer);
RELEASEINTERFACE(m_pApplicationFonts);

View File

@ -555,12 +555,12 @@ namespace NSJSON
#ifdef JSON_DEBUG
throw std::bad_cast();
#endif
return ifInvalid;
return ImageFormat::ifInvalid;
}
return static_cast<CImage*>(m_internal->m_value.get())->getFormat();
}
void IValue::Externalize()
void IValue::ImageExternalize()
{
if (m_internal->m_type != CTypedValue::vtImage)
{
@ -572,6 +572,18 @@ namespace NSJSON
static_cast<CImage*>(m_internal->m_value.get())->externalize();
}
void IValue::ImageAlloc(const int& width, const int& height, const ImageFormat& format)
{
if (m_internal->m_type != CTypedValue::vtImage)
{
#ifdef JSON_DEBUG
throw std::bad_cast();
#endif
return;
}
static_cast<CImage*>(m_internal->m_value.get())->alloc(width, height, format);
}
CValue::CValue() : IValue()
{
}
@ -675,9 +687,17 @@ namespace NSJSON
return ret;
}
CValue CValue::CreateEmptyImage(ImageFormat format)
{
CValue ret;
ret.m_internal->m_value = std::make_shared<CImage>((BYTE*)NULL, 0, 0, format, false);
ret.m_internal->m_type = CTypedValue::vtImage;
return ret;
}
BYTE* CValue::AllocImageBits(int width, int height)
{
return new BYTE[width * height];
return new BYTE[4 * width * height];
}
void CValue::FreeImageBits(BYTE* bits)

View File

@ -30,7 +30,7 @@ namespace NSJSON
{
typedef unsigned char BYTE;
enum ImageFormat
enum class ImageFormat
{
ifRGBA,
ifBGRA,
@ -231,7 +231,12 @@ namespace NSJSON
/**
* Make image bits external.
*/
void Externalize();
void ImageExternalize();
/**
* Alloc image bits as internal.
*/
void ImageAlloc(const int& width, const int& height, const ImageFormat& format);
protected:
std::shared_ptr<CTypedValue> m_internal;
@ -301,7 +306,8 @@ namespace NSJSON
* @param isExternalize If true the memory will not be reclaimed when the created image is destroyed.
* If this parameter is false then the memory will be released using FreeImageBits() during the image object destruction.
*/
static CValue CreateImage(BYTE* bits, int width, int height, ImageFormat format = ifBGRA, bool isExternalize = true);
static CValue CreateImage(BYTE* bits, int width, int height, ImageFormat format = ImageFormat::ifBGRA, bool isExternalize = true);
static CValue CreateEmptyImage(ImageFormat format = ImageFormat::ifBGRA);
/**
* Allocates the memory for an image.
* @param width The width of the image.

View File

@ -212,7 +212,8 @@ namespace NSJSON
return ret;
}
CImage::CImage(BYTE* bits, int width, int height, ImageFormat format, bool isExternalize) : m_bits(bits), m_width(width), m_height(height), m_format(format), m_isExternalize(isExternalize)
CImage::CImage(BYTE* bits, const int& width, const int& height, const ImageFormat& format, const bool& isExternalize) :
m_bits(bits), m_width(width), m_height(height), m_format(format), m_isExternalize(isExternalize)
{
}
@ -224,6 +225,20 @@ namespace NSJSON
}
}
void CImage::alloc(const int& width, const int& height, const ImageFormat& format)
{
if (!m_isExternalize && m_bits)
{
CValue::FreeImageBits(m_bits);
}
m_bits = CValue::AllocImageBits(width, height);
m_width = width;
m_height = height;
m_format = format;
m_isExternalize = false;
}
BYTE* CImage::getBits()
{
return m_bits;

View File

@ -117,7 +117,7 @@ namespace NSJSON
class CImage : public IBaseValue
{
public:
CImage(BYTE* bits, int width, int height, ImageFormat format, bool isExternalize = true);
CImage(BYTE* bits, const int& width, const int& height, const ImageFormat& format, const bool& isExternalize = true);
~CImage();
public:
@ -126,6 +126,7 @@ namespace NSJSON
int getHeight();
ImageFormat getFormat();
void externalize();
void alloc(const int& width, const int& height, const ImageFormat& format);
private:
BYTE* m_bits;

View File

@ -3,14 +3,49 @@
#include "json.h"
#include "../js_internal/js_base.h"
#include "../embed/GraphicsEmbed.h"
#include <cmath>
class CAppImage : public CGraphicsAppImage
{
private:
NSJSON::CValueRef* m_image;
public:
CAppImage(const NSJSON::CValue& image) : CGraphicsAppImage()
{
m_image = new NSJSON::CValueRef(image);
}
virtual ~CAppImage()
{
if (m_image)
delete m_image;
}
public:
virtual unsigned char* GetBits(int& w, int& h)
{
unsigned char* bits = m_image->GetImageBits();
if (NULL != bits)
{
w = m_image->GetImageWidth();
h = m_image->GetImageHeight();
}
return bits;
}
virtual unsigned char* AllocBits(const int& w, const int& h)
{
m_image->ImageAlloc(w, h, GetRgba() ? NSJSON::ImageFormat::ifRGBA : NSJSON::ImageFormat::ifBGRA);
return m_image->GetImageBits();
}
};
namespace NSJSON
{
static JSSmart<NSJSBase::CJSValue> toJS(const CValue& value)
{
if (value.IsUndefined() || value.IsImage())
if (value.IsUndefined())
return NSJSBase::CJSContext::createUndefined();
if (value.IsNull())
return NSJSBase::CJSContext::createNull();
@ -50,6 +85,12 @@ namespace NSJSON
JSSmart<NSJSBase::CJSTypedArray> jsTypedArr = NSJSBase::CJSContext::createUint8Array(const_cast<BYTE*>(value.GetData()), value.GetCount());
ret = jsTypedArr->toValue();
}
else if (value.IsImage())
{
JSSmart<CJSObject> wrap = CJSContext::createEmbedObject("CGraphicsEmbed");
((CGraphicsEmbed*)wrap->getNative())->SetAppImage(new CAppImage(value));
ret = wrap->toValue();
}
// objects (there is no need for IsObject())
else
{