28#if defined IGRAPHICS_SKIA && !defined IGRAPHICS_NO_SKIA_SVG
33 #pragma warning( push )
34 #pragma warning( disable : 4244 )
35 #pragma warning( disable : 5030 )
36 #include "modules/svg/include/SkSVGDOM.h"
37 #include "include/core/SkCanvas.h"
38 #include "include/core/SkStream.h"
39 #include "src/xml/SkDOM.h"
40 #pragma warning( pop )
41 #pragma comment(lib, "svg.lib")
42 #pragma comment(lib, "skshaper.lib")
43 #pragma comment(lib, "skunicode_core.lib")
44 #pragma comment(lib, "skunicode_icu.lib")
51#if defined IGRAPHICS_NANOVG
52 #define BITMAP_DATA_TYPE int;
53#elif defined IGRAPHICS_SKIA
54 #pragma warning( push )
55 #pragma warning( disable : 4244 )
56 #include "include/core/SkImage.h"
57 #include "include/core/SkSurface.h"
58 #pragma warning( pop )
62 sk_sp<SkImage> mImage;
63 sk_sp<SkSurface> mSurface;
65 #define BITMAP_DATA_TYPE SkiaDrawable*
66#elif defined IGRAPHICS_CANVAS
67 #include <emscripten.h>
68 #include <emscripten/val.h>
69 #define BITMAP_DATA_TYPE emscripten::val*
71 #define BITMAP_DATA_TYPE void*;
74#if defined OS_MAC || defined OS_IOS
75 #include <CoreText/CoreText.h>
76 #define FONT_DESCRIPTOR_TYPE CTFontDescriptorRef
79 #define FONT_DESCRIPTOR_TYPE HFONT
81 #define FONT_DESCRIPTOR_TYPE std::pair<WDL_String, WDL_String>*
87BEGIN_IGRAPHICS_NAMESPACE
88using BitmapData = BITMAP_DATA_TYPE;
89using FontDescriptor = FONT_DESCRIPTOR_TYPE;
90using RawBitmapData = WDL_TypedBuf<uint8_t>;
105 APIBitmap(BitmapData pBitmap,
int w,
int h,
float scale,
float drawScale)
110 , mDrawScale(drawScale)
132 void SetBitmap(BitmapData pBitmap,
int w,
int h,
float scale,
float drawScale)
138 mDrawScale = drawScale;
168 IFontInfo(
const void* data, uint32_t dataSize, uint32_t faceIdx)
169 : mData(reinterpret_cast<const unsigned char*>(data))
176 mHeadLocation = LocateTable(
"head");
177 mNameLocation = LocateTable(
"name");
178 mHheaLocation = LocateTable(
"hhea");
179 mFDscLocation = LocateTable(
"fdsc");
183 mUnitsPerEM = GetUInt16(mHeadLocation + 18);
184 mMacStyle = GetUInt16(mHeadLocation + 44);
185 mFamily = SearchFontString(1);
186 mStyle = SearchFontString(2);
187 mAscender = GetSInt16(mHheaLocation + 4);
188 mDescender = GetSInt16(mHheaLocation + 6);
189 mLineGap = GetSInt16(mHheaLocation + 8);
194 bool IsValid()
const {
return mData && mHeadLocation && mNameLocation && mHheaLocation; }
196 const WDL_String& GetFamily()
const {
return mFamily; }
197 const WDL_String& GetStyle()
const {
return mStyle; }
199 bool IsBold()
const {
return mMacStyle & (1 << 0); }
200 bool IsItalic()
const {
return mMacStyle & (1 << 1); }
201 bool IsUnderline()
const {
return mMacStyle & (1 << 2); }
202 bool IsOutline()
const {
return mMacStyle & (1 << 3); }
203 bool IsShadow()
const {
return mMacStyle & (1 << 4); }
204 bool IsCondensed()
const {
return mMacStyle & (1 << 5); }
205 bool IsExpanded()
const {
return mMacStyle & (1 << 6); }
207 double GetHeightEMRatio()
const {
return mUnitsPerEM /
static_cast<double>(mAscender - mDescender); }
209 uint16_t GetUnitsPerEM()
const {
return mUnitsPerEM; }
210 int16_t GetAscender()
const {
return mAscender; }
211 int16_t GetDescender()
const {
return mDescender; }
212 int16_t GetLineGap()
const {
return mLineGap; }
213 int16_t GetLineHeight()
const {
return (mAscender - mDescender) + mLineGap; }
217 enum class EStringID { Mac, Windows };
219 bool MatchTag(uint32_t loc,
const char* tag)
221 return mData[loc+0] == tag[0] && mData[loc+1] == tag[1] && mData[loc+2] == tag[2] && mData[loc+3] == tag[3];
224 uint32_t LocateTable(
const char *tag)
226 uint16_t numTables = GetUInt16(4);
228 for (uint16_t i = 0; i < numTables; ++i)
230 uint32_t tableLocation = 12 + (16 * i);
231 if (MatchTag(tableLocation, tag))
232 return GetUInt32(tableLocation + 8);
238 WDL_String SearchFontString(
int nameID)
240 WDL_String str = GetFontString(nameID, EStringID::Windows);
245 return GetFontString(nameID, EStringID::Mac);
248 WDL_String GetFontString(
int nameID, EStringID stringID)
254 int languageID = 0x409;
264 case EStringID::Windows:
268 for (uint16_t i = 0; i < GetUInt16(mNameLocation + 2); ++i)
270 uint32_t loc = mNameLocation + 6 + (12 * i);
272 if (platformID == GetUInt16(loc + 0) && encodingID == GetUInt16(loc + 2)
273 && languageID == GetUInt16(loc + 4) && nameID == GetUInt16(loc + 6))
275 uint32_t stringLocation = GetUInt16(mNameLocation + 4) + GetUInt16(loc + 10);
276 uint16_t length = GetUInt16(loc + 8);
280 case EStringID::Windows:
282 WDL_TypedBuf<char> utf8;
283 WDL_TypedBuf<char16_t> utf16;
284 utf8.Resize((length * 3) / 2);
285 utf16.Resize(length /
sizeof(
char16_t));
287 for (
int j = 0; j < length; j++)
288 utf16.Get()[j] = GetUInt16(mNameLocation + stringLocation + j * 2);
290 std::codecvt_utf8_utf16<char16_t> conv;
294 memset(&mbs, 0,
sizeof(mbs));
295 conv.out(mbs, utf16.Get(), utf16.Get() + utf16.GetSize(), a, utf8.Get(), utf8.Get() + utf8.GetSize(), b);
297 return WDL_String(utf8.Get(), (
int) (b - utf8.Get()));
301 return WDL_String((
const char*)(mData + mNameLocation + stringLocation), length);
309 void FindFace(uint32_t faceIdx)
311 bool singleFont = IsSingleFont();
313 if (singleFont && faceIdx == 0 )
317 if (!singleFont && MatchTag(0,
"ttcf"))
320 if (GetUInt32(4) == 0x00010000 || GetUInt32(4) == 0x00020000)
322 if (faceIdx < GetSInt32(8))
324 mData += GetUInt32(12 + faceIdx * 4);
334 char TTV1[4] = {
'1', 0, 0, 0 };
335 char OTV1[4] = { 0, 1, 0, 0 };
338 if (MatchTag(0, TTV1))
return true;
339 if (MatchTag(0,
"typ1"))
return true;
340 if (MatchTag(0,
"OTTO"))
return true;
341 if (MatchTag(0, OTV1))
return true;
346#if defined WDL_LITTLE_ENDIAN
347 uint16_t GetUInt16(uint32_t loc) {
return (((uint16_t)mData[loc + 0]) << 8) | (uint16_t)mData[loc + 1]; }
348 int16_t GetSInt16(uint32_t loc) {
return (((uint16_t)mData[loc + 0]) << 8) | (uint16_t)mData[loc + 1]; }
349 uint32_t GetUInt32(uint32_t loc) {
return (((uint32_t)GetUInt16(loc + 0)) << 16) | (uint32_t)GetUInt16(loc + 2); }
350 int32_t GetSInt32(uint32_t loc) {
return (((uint32_t)GetUInt16(loc + 0)) << 16) | (uint32_t)GetUInt16(loc + 2); }
352 uint16_t GetUInt16(uint32_t loc) {
return (((uint16_t)mData[loc + 1]) << 8) | (uint16_t)mData[loc + 0]; }
353 int16_t GetSInt16(uint32_t loc) {
return (((uint16_t)mData[loc + 1]) << 8) | (uint16_t)mData[loc + 0]; }
354 uint32_t GetUInt32(uint32_t loc) {
return (((uint32_t)GetUInt16(loc + 2)) << 16) | (uint32_t)GetUInt16(loc + 0); }
355 int32_t GetSInt32(uint32_t loc) {
return (((uint32_t)GetUInt16(loc + 2)) << 16) | (uint32_t)GetUInt16(loc + 0); }
359 const unsigned char* mData;
361 uint32_t mHeadLocation = 0;
362 uint32_t mNameLocation = 0;
363 uint32_t mHheaLocation = 0;
364 uint32_t mFDscLocation = 0;
369 uint16_t mMacStyle = 0;
372 uint16_t mUnitsPerEM = 0;
373 int16_t mAscender = 0;
374 int16_t mDescender = 0;
375 int16_t mLineGap = 0;
379class IFontData :
public IFontInfo,
private WDL_TypedBuf<unsigned char>
382 IFontData() : IFontInfo(nullptr, 0, -1), mFaceIdx(-1) {}
384 IFontData(
const void* data,
int size,
int faceIdx) : IFontInfo(data, size, faceIdx), mFaceIdx(faceIdx)
386 const unsigned char* src =
reinterpret_cast<const unsigned char*
>(data);
387 unsigned char* dest = ResizeOK(size);
390 std::copy(src, src + size, dest);
393 IFontData(
int size) : IFontInfo(nullptr, 0, -1), mFaceIdx(-1)
398 void SetFaceIdx(
int faceIdx)
401 static_cast<IFontData&
>(*this) = IFontData(Get(), GetSize(), mFaceIdx);
404 bool IsValid()
const {
return GetSize() && mFaceIdx >= 0 && IFontInfo::IsValid(); }
406 unsigned char* Get() {
return WDL_TypedBuf<unsigned char>::Get(); }
407 int GetSize()
const {
return WDL_TypedBuf<unsigned char>::GetSize(); }
408 int GetFaceIdx()
const {
return mFaceIdx; }
415using IFontDataPtr = std::unique_ptr<IFontData>;
421 PlatformFont(
bool system) : mSystem(system) {}
422 virtual ~PlatformFont() {}
424 PlatformFont(
const PlatformFont&) =
delete;
425 PlatformFont& operator=(
const PlatformFont&) =
delete;
427 virtual FontDescriptor GetDescriptor() {
return nullptr; }
428 virtual IFontDataPtr GetFontData() {
return IFontDataPtr(
new IFontData()); }
429 bool IsSystem() {
return mSystem; }
432 int GetFaceIdx(
const void* data,
int dataSize,
const char* styleName)
434 for (
int idx = 0; ; idx++)
436 IFontInfo fontInfo(data, dataSize, idx);
438 if (!fontInfo.IsValid())
441 const WDL_String& style = fontInfo.GetStyle();
443 if (style.GetLength() && (!styleName[0] || !strcmp(style.Get(), styleName)))
451using PlatformFontPtr = std::unique_ptr<PlatformFont>;
456 SVGHolder(sk_sp<SkSVGDOM> svgDom)
466 SVGHolder(
const SVGHolder&) =
delete;
467 SVGHolder& operator=(
const SVGHolder&) =
delete;
469 sk_sp<SkSVGDOM> mSVGDom;
475 SVGHolder(NSVGimage* pImage)
488 SVGHolder(
const SVGHolder&) =
delete;
489 SVGHolder& operator=(
const SVGHolder&) =
delete;
491 NSVGimage* mImage =
nullptr;
501 class Accessor :
private WDL_MutexLock
504 Accessor(StaticStorage& storage)
505 : WDL_MutexLock(&storage.mMutex)
509 T* Find(
const char* str,
double scale = 1.) {
return mStorage.Find(str, scale); }
510 void Add(T* pData,
const char* str,
double scale = 1.) {
return mStorage.Add(pData, str, scale); }
511 void Remove(T* pData) {
return mStorage.Remove(pData); }
512 void Clear() {
return mStorage.Clear(); }
513 void Retain() {
return mStorage.Retain(); }
514 void Release() {
return mStorage.Release(); }
517 StaticStorage& mStorage;
527 StaticStorage(
const StaticStorage&) =
delete;
528 StaticStorage& operator=(
const StaticStorage&) =
delete;
538 std::unique_ptr<T> data;
544 size_t Hash(
const char* str)
546 std::string string(str);
547 return std::hash<std::string>()(string);
554 T* Find(
const char* str,
double scale = 1.)
556 WDL_String cacheName(str);
557 cacheName.AppendFormatted((
int) strlen(str) + 6,
"-%.1fx", scale);
559 size_t hashID = Hash(cacheName.Get());
561 int i, n = mDatas.GetSize();
562 for (i = 0; i < n; ++i)
564 DataKey* pKey = mDatas.Get(i);
567 if (pKey->hashID == hashID && scale == pKey->scale && !strcmp(str, pKey->name.Get()))
568 return pKey->data.get();
577 void Add(T* pData,
const char* str,
double scale = 1.)
579 DataKey* pKey = mDatas.Add(
new DataKey);
581 WDL_String cacheName(str);
582 cacheName.AppendFormatted((
int) strlen(str) + 6,
"-%.1fx", scale);
584 pKey->hashID = Hash(cacheName.Get());
585 pKey->data = std::unique_ptr<T>(pData);
593 void Remove(T* pData)
595 for (
int i = 0; i < mDatas.GetSize(); ++i)
597 if (mDatas.Get(i)->data.get() == pData)
599 mDatas.Delete(i,
true);
626 WDL_PtrList<DataKey> mDatas;
634 IVec2(
float x,
float y) : x(x), y(y) {}
640END_IGRAPHICS_NAMESPACE
A base class interface for a bitmap abstraction around the different drawing back end bitmap represen...
APIBitmap(BitmapData pBitmap, int w, int h, float scale, float drawScale)
APIBitmap constructor.
BitmapData GetBitmap() const
void SetBitmap(BitmapData pBitmap, int w, int h, float scale, float drawScale)
Used to initialise the members after construction.
float GetDrawScale() const
Encapsulate an xy point in one struct.