23 #include "wdlstring.h" 24 #include "wdlendian.h" 29 #pragma warning( push ) 30 #pragma warning( disable : 4244 ) 31 #pragma warning( disable : 5030 ) 33 #include "include/core/SkCanvas.h" 34 #include "include/core/SkStream.h" 35 #include "src/xml/SkDOM.h" 36 #pragma warning( pop ) 43 #if defined IGRAPHICS_NANOVG 44 #define BITMAP_DATA_TYPE int; 45 #elif defined IGRAPHICS_SKIA 46 #pragma warning( push ) 47 #pragma warning( disable : 4244 ) 49 #include "SkSurface.h" 50 #pragma warning( pop ) 54 sk_sp<SkImage> mImage;
55 sk_sp<SkSurface> mSurface;
57 #define BITMAP_DATA_TYPE SkiaDrawable* 58 #elif defined IGRAPHICS_CANVAS 59 #include <emscripten.h> 60 #include <emscripten/val.h> 61 #define BITMAP_DATA_TYPE emscripten::val* 63 #define BITMAP_DATA_TYPE void*; 66 #if defined OS_MAC || defined OS_IOS 67 #include <CoreText/CoreText.h> 68 #define FONT_DESCRIPTOR_TYPE CTFontDescriptorRef 71 #define FONT_DESCRIPTOR_TYPE HFONT 73 #define FONT_DESCRIPTOR_TYPE std::pair<WDL_String, WDL_String>* 79 BEGIN_IGRAPHICS_NAMESPACE
80 using BitmapData = BITMAP_DATA_TYPE;
81 using FontDescriptor = FONT_DESCRIPTOR_TYPE;
82 using RawBitmapData = WDL_TypedBuf<uint8_t>;
97 APIBitmap(BitmapData pBitmap,
int w,
int h,
int scale,
float drawScale)
102 , mDrawScale(drawScale)
124 void SetBitmap(BitmapData pBitmap,
int w,
int h,
int scale,
float drawScale)
130 mDrawScale = drawScale;
160 IFontInfo(
const void* data, uint32_t dataSize, uint32_t faceIdx)
161 : mData(reinterpret_cast<const unsigned char*>(data))
168 mHeadLocation = LocateTable(
"head");
169 mNameLocation = LocateTable(
"name");
170 mHheaLocation = LocateTable(
"hhea");
171 mFDscLocation = LocateTable(
"fdsc");
175 mUnitsPerEM = GetUInt16(mHeadLocation + 18);
176 mMacStyle = GetUInt16(mHeadLocation + 44);
177 mFamily = SearchFontString(1);
178 mStyle = SearchFontString(2);
179 mAscender = GetSInt16(mHheaLocation + 4);
180 mDescender = GetSInt16(mHheaLocation + 6);
181 mLineGap = GetSInt16(mHheaLocation + 8);
186 bool IsValid()
const {
return mData && mHeadLocation && mNameLocation && mHheaLocation; }
188 const WDL_String& GetFamily()
const {
return mFamily; }
189 const WDL_String& GetStyle()
const {
return mStyle; }
191 bool IsBold()
const {
return mMacStyle & (1 << 0); }
192 bool IsItalic()
const {
return mMacStyle & (1 << 1); }
193 bool IsUnderline()
const {
return mMacStyle & (1 << 2); }
194 bool IsOutline()
const {
return mMacStyle & (1 << 3); }
195 bool IsShadow()
const {
return mMacStyle & (1 << 4); }
196 bool IsCondensed()
const {
return mMacStyle & (1 << 5); }
197 bool IsExpanded()
const {
return mMacStyle & (1 << 6); }
199 double GetHeightEMRatio()
const {
return mUnitsPerEM /
static_cast<double>(mAscender - mDescender); }
201 uint16_t GetUnitsPerEM()
const {
return mUnitsPerEM; }
202 int16_t GetAscender()
const {
return mAscender; }
203 int16_t GetDescender()
const {
return mDescender; }
204 int16_t GetLineGap()
const {
return mLineGap; }
205 int16_t GetLineHeight()
const {
return (mAscender - mDescender) + mLineGap; }
209 enum class EStringID { Mac, Windows };
211 bool MatchTag(uint32_t loc,
const char* tag)
213 return mData[loc+0] == tag[0] && mData[loc+1] == tag[1] && mData[loc+2] == tag[2] && mData[loc+3] == tag[3];
216 uint32_t LocateTable(
const char *tag)
218 uint16_t numTables = GetUInt16(4);
220 for (uint16_t i = 0; i < numTables; ++i)
222 uint32_t tableLocation = 12 + (16 * i);
223 if (MatchTag(tableLocation, tag))
224 return GetUInt32(tableLocation + 8);
230 WDL_String SearchFontString(
int nameID)
232 WDL_String str = GetFontString(nameID, EStringID::Windows);
237 return GetFontString(nameID, EStringID::Mac);
240 WDL_String GetFontString(
int nameID, EStringID stringID)
246 int languageID = 0x409;
256 case EStringID::Windows:
260 for (uint16_t i = 0; i < GetUInt16(mNameLocation + 2); ++i)
262 uint32_t loc = mNameLocation + 6 + (12 * i);
264 if (platformID == GetUInt16(loc + 0) && encodingID == GetUInt16(loc + 2)
265 && languageID == GetUInt16(loc + 4) && nameID == GetUInt16(loc + 6))
267 uint32_t stringLocation = GetUInt16(mNameLocation + 4) + GetUInt16(loc + 10);
268 uint16_t length = GetUInt16(loc + 8);
272 case EStringID::Windows:
274 WDL_TypedBuf<char> utf8;
275 WDL_TypedBuf<char16_t> utf16;
276 utf8.Resize((length * 3) / 2);
277 utf16.Resize(length /
sizeof(char16_t));
279 for (
int j = 0; j < length; j++)
280 utf16.Get()[j] = GetUInt16(mNameLocation + stringLocation + j * 2);
282 std::codecvt_utf8_utf16<char16_t> conv;
286 memset(&mbs, 0,
sizeof(mbs));
287 conv.out(mbs, utf16.Get(), utf16.Get() + utf16.GetSize(), a, utf8.Get(), utf8.Get() + utf8.GetSize(), b);
289 return WDL_String(utf8.Get(), (int) (b - utf8.Get()));
293 return WDL_String((
const char*)(mData + mNameLocation + stringLocation), length);
301 void FindFace(uint32_t faceIdx)
303 bool singleFont = IsSingleFont();
305 if (singleFont && faceIdx == 0 )
309 if (!singleFont && MatchTag(0,
"ttcf"))
312 if (GetUInt32(4) == 0x00010000 || GetUInt32(4) == 0x00020000)
314 if (faceIdx < GetSInt32(8))
316 mData += GetUInt32(12 + faceIdx * 4);
326 char TTV1[4] = {
'1', 0, 0, 0 };
327 char OTV1[4] = { 0, 1, 0, 0 };
330 if (MatchTag(0, TTV1))
return true;
331 if (MatchTag(0,
"typ1"))
return true;
332 if (MatchTag(0,
"OTTO"))
return true;
333 if (MatchTag(0, OTV1))
return true;
338 #if defined WDL_LITTLE_ENDIAN 339 uint16_t GetUInt16(uint32_t loc) {
return (((uint16_t)mData[loc + 0]) << 8) | (uint16_t)mData[loc + 1]; }
340 int16_t GetSInt16(uint32_t loc) {
return (((uint16_t)mData[loc + 0]) << 8) | (uint16_t)mData[loc + 1]; }
341 uint32_t GetUInt32(uint32_t loc) {
return (((uint32_t)GetUInt16(loc + 0)) << 16) | (uint32_t)GetUInt16(loc + 2); }
342 int32_t GetSInt32(uint32_t loc) {
return (((uint32_t)GetUInt16(loc + 0)) << 16) | (uint32_t)GetUInt16(loc + 2); }
344 uint16_t GetUInt16(uint32_t loc) {
return (((uint16_t)mData[loc + 1]) << 8) | (uint16_t)mData[loc + 0]; }
345 int16_t GetSInt16(uint32_t loc) {
return (((uint16_t)mData[loc + 1]) << 8) | (uint16_t)mData[loc + 0]; }
346 uint32_t GetUInt32(uint32_t loc) {
return (((uint32_t)GetUInt16(loc + 2)) << 16) | (uint32_t)GetUInt16(loc + 0); }
347 int32_t GetSInt32(uint32_t loc) {
return (((uint32_t)GetUInt16(loc + 2)) << 16) | (uint32_t)GetUInt16(loc + 0); }
351 const unsigned char* mData;
353 uint32_t mHeadLocation = 0;
354 uint32_t mNameLocation = 0;
355 uint32_t mHheaLocation = 0;
356 uint32_t mFDscLocation = 0;
361 uint16_t mMacStyle = 0;
364 uint16_t mUnitsPerEM = 0;
365 int16_t mAscender = 0;
366 int16_t mDescender = 0;
367 int16_t mLineGap = 0;
371 class IFontData :
public IFontInfo,
private WDL_TypedBuf<unsigned char>
374 IFontData() : IFontInfo(
nullptr, 0, -1), mFaceIdx(-1) {}
376 IFontData(
const void* data,
int size,
int faceIdx) : IFontInfo(data, size, faceIdx), mFaceIdx(faceIdx)
378 const unsigned char* src =
reinterpret_cast<const unsigned char*
>(data);
379 unsigned char* dest = ResizeOK(size);
382 std::copy(src, src + size, dest);
385 IFontData(
int size) : IFontInfo(
nullptr, 0, -1), mFaceIdx(-1)
390 void SetFaceIdx(
int faceIdx)
393 static_cast<IFontData&
>(*this) = IFontData(Get(), GetSize(), mFaceIdx);
396 bool IsValid()
const {
return GetSize() && mFaceIdx >= 0 && IFontInfo::IsValid(); }
398 unsigned char* Get() {
return WDL_TypedBuf<unsigned char>::Get(); }
399 int GetSize()
const {
return WDL_TypedBuf<unsigned char>::GetSize(); }
400 int GetFaceIdx()
const {
return mFaceIdx; }
407 using IFontDataPtr = std::unique_ptr<IFontData>;
413 PlatformFont(
bool system) : mSystem(system) {}
414 virtual ~PlatformFont() {}
416 PlatformFont(
const PlatformFont&) =
delete;
417 PlatformFont& operator=(
const PlatformFont&) =
delete;
419 virtual FontDescriptor GetDescriptor() {
return nullptr; }
420 virtual IFontDataPtr GetFontData() {
return IFontDataPtr(
new IFontData()); }
421 bool IsSystem() {
return mSystem; }
424 int GetFaceIdx(
const void* data,
int dataSize,
const char* styleName)
426 for (
int idx = 0; ; idx++)
428 IFontInfo fontInfo(data, dataSize, idx);
430 if (!fontInfo.IsValid())
433 const WDL_String& style = fontInfo.GetStyle();
435 if (style.GetLength() && (!styleName[0] || !strcmp(style.Get(), styleName)))
443 using PlatformFontPtr = std::unique_ptr<PlatformFont>;
445 #ifdef IGRAPHICS_SKIA 448 SVGHolder(sk_sp<SkSVGDOM> svgDom)
458 SVGHolder(
const SVGHolder&) =
delete;
459 SVGHolder& operator=(
const SVGHolder&) =
delete;
461 sk_sp<SkSVGDOM> mSVGDom;
467 SVGHolder(NSVGimage* pImage)
480 SVGHolder(
const SVGHolder&) =
delete;
481 SVGHolder& operator=(
const SVGHolder&) =
delete;
483 NSVGimage* mImage =
nullptr;
493 class Accessor :
private WDL_MutexLock
496 Accessor(StaticStorage& storage)
497 : WDL_MutexLock(&storage.mMutex)
501 T* Find(
const char* str,
double scale = 1.) {
return mStorage.Find(str, scale); }
502 void Add(T* pData,
const char* str,
double scale = 1.) {
return mStorage.Add(pData, str, scale); }
503 void Remove(T* pData) {
return mStorage.Remove(pData); }
504 void Clear() {
return mStorage.Clear(); }
505 void Retain() {
return mStorage.Retain(); }
506 void Release() {
return mStorage.Release(); }
509 StaticStorage& mStorage;
519 StaticStorage(
const StaticStorage&) =
delete;
520 StaticStorage& operator=(
const StaticStorage&) =
delete;
530 std::unique_ptr<T> data;
536 size_t Hash(
const char* str)
538 std::string string(str);
539 return std::hash<std::string>()(
string);
546 T* Find(
const char* str,
double scale = 1.)
548 WDL_String cacheName(str);
549 cacheName.AppendFormatted((
int) strlen(str) + 6,
"-%.1fx", scale);
551 size_t hashID = Hash(cacheName.Get());
553 int i, n = mDatas.GetSize();
554 for (i = 0; i < n; ++i)
556 DataKey* pKey = mDatas.Get(i);
559 if (pKey->hashID == hashID && scale == pKey->scale && !strcmp(str, pKey->name.Get()))
560 return pKey->data.get();
569 void Add(T* pData,
const char* str,
double scale = 1.)
571 DataKey* pKey = mDatas.Add(
new DataKey);
573 WDL_String cacheName(str);
574 cacheName.AppendFormatted((
int) strlen(str) + 6,
"-%.1fx", scale);
576 pKey->hashID = Hash(cacheName.Get());
577 pKey->data = std::unique_ptr<T>(pData);
585 void Remove(T* pData)
587 for (
int i = 0; i < mDatas.GetSize(); ++i)
589 if (mDatas.Get(i)->data.get() == pData)
591 mDatas.Delete(i,
true);
618 WDL_PtrList<DataKey> mDatas;
626 IVec2(
float x,
float y) : x(x), y(y) {}
633 END_IGRAPHICS_NAMESPACE
Encapsulate an xy point in one struct.
void SetBitmap(BitmapData pBitmap, int w, int h, int scale, float drawScale)
Used to initialise the members after construction.
BitmapData GetBitmap() const
float GetDrawScale() const
A base class interface for a bitmap abstraction around the different drawing back end bitmap represen...
APIBitmap(BitmapData pBitmap, int w, int h, int scale, float drawScale)
APIBitmap constructor.