diff --git a/windows/CMakeLists.txt b/windows/CMakeLists.txt index f4a10998..739c1300 100644 --- a/windows/CMakeLists.txt +++ b/windows/CMakeLists.txt @@ -38,6 +38,7 @@ list(APPEND _LIBUI_SOURCES windows/main.cpp windows/menu.cpp windows/multilineentry.cpp + windows/opentype.cpp windows/parent.cpp windows/progressbar.cpp windows/radiobuttons.cpp diff --git a/windows/opentype.cpp b/windows/opentype.cpp index 4273b80f..21e681b7 100644 --- a/windows/opentype.cpp +++ b/windows/opentype.cpp @@ -1,8 +1,10 @@ // 11 may 2017 #include "uipriv_windows.hpp" +typedef std::map tagmap; + struct uiOpenTypeFeatures { - xxxx; + tagmap *tags; }; uiOpenTypeFeatures *uiNewOpenTypeFeatures(void) @@ -10,13 +12,13 @@ uiOpenTypeFeatures *uiNewOpenTypeFeatures(void) uiOpenTypeFeatures *otf; otf = uiNew(uiOpenTypeFeatures); - xxxx; + otf->tags = new tagmap; return otf; } void uiFreeOpenTypeFeatures(uiOpenTypeFeatures *otf) { - xxxxxx; + delete otf->tags; uiFree(otf); } @@ -25,28 +27,79 @@ uiOpenTypeFeatures *uiOpenTypeFeaturesClone(uiOpenTypeFeatures *otf) uiOpenTypeFeatures *out; out = uiNew(uiOpenTypeFeatures); - xxxxxx; + out->tags = new tagmap; + *(out->tags) = *(otf->tags); return out; } +#define mktag(a, b, c, d) ((uint32_t) DWRITE_MAKE_OPENTYPE_TAG(a, b, c, d)) + void uiOpenTypeFeaturesAdd(uiOpenTypeFeatures *otf, char a, char b, char c, char d, uint32_t value) { + (*(otf->tags))[mktag(a, b, c, d)] = value; } +// TODO what should happen if a/b/c/d isn't defined? +// TODO what does std::map do if a/b/c/d isn't defined? void uiOpenTypeFeaturesRemove(uiOpenTypeFeatures *otf, char a, char b, char c, char d) { + otf->tags->erase(mktag(a, b, c, d)); } int uiOpenTypeFeaturesGet(uiOpenTypeFeatures *otf, char a, char b, char c, char d, uint32_t *value) { + tagmap::const_iterator iter; + + iter = otf->tags->find(mktag(a, b, c, d)); + if (iter == otf->tags->end()) + return 0; + *value = iter->second; + return 1; } void uiOpenTypeFeaturesForEach(uiOpenTypeFeatures *otf, uiOpenTypeFeaturesForEachFunc f, void *data) { + tagmap::const_iterator iter, end; + + end = otf->tags->end(); + for (iter = otf->tags->begin(); iter != end; iter++) { + uint8_t a, b, c, d; + + a = (uint8_t) (iter->first & 0xFF); + b = (uint8_t) ((iter->first >> 8) & 0xFF); + c = (uint8_t) ((iter->first >> 16) & 0xFF); + d = (uint8_t) ((iter->first >> 24) & 0xFF); + // TODO handle return value + (*f)((char) a, (char) b, (char) c, (char) d, + iter->second, data); + } } +// TODO wait, is this function even necessary? how do we unify attributes?? int uiOpenTypeFeaturesEqual(uiOpenTypeFeatures *a, uiOpenTypeFeatures *b) { + // TODO make sure this is correct + return *(a->tags) == *(b->tags); } -// TODO put the internal function to produce a backend object from one here +IDWriteTypography *otfToDirectWrite(uiOpenTypeFeatures *otf) +{ + IDWriteTypography *dt; + tagmap::const_iterator iter, end; + DWRITE_FONT_FEATURE dff; + HRESULT hr; + + hr = dwfactory->CreateTypography(&dt); + if (hr != S_OK) + logHRESULT(L"error creating IDWriteTypography", hr); + end = otf->tags->end(); + for (iter = otf->tags->begin(); iter != end; iter++) { + ZeroMemory(&dff, sizeof (DWRITE_FONT_FEATURE)); + dff.nameTag = (DWRITE_FONT_FEATURE_TAG) (iter->first); + dff.parameter = (UINT32) (iter->second); + hr = dt->AddFontFeature(dff); + if (hr != S_OK) + logHRESULT(L"error adding OpenType feature to IDWriteTypography", hr); + } + return dt; +} diff --git a/windows/uipriv_windows.hpp b/windows/uipriv_windows.hpp index f1de95cf..aa39dd07 100644 --- a/windows/uipriv_windows.hpp +++ b/windows/uipriv_windows.hpp @@ -162,3 +162,6 @@ extern ID2D1DCRenderTarget *makeHDCRenderTarget(HDC dc, RECT *r); // drawtext.cpp extern void fontdescFromIDWriteFont(IDWriteFont *font, uiDrawFontDescriptor *uidesc); + +// opentype.cpp +extern IDWriteTypography *otfToDirectWrite(uiOpenTypeFeatures *otf);