Basic opentype features support

This commit is contained in:
Ebrahim Byagowi 2016-03-31 18:19:44 +00:00
parent d129897120
commit 10c3d9e415
1 changed files with 42 additions and 20 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright © 2015 Ebrahim Byagowi * Copyright © 2015-2016 Ebrahim Byagowi
* *
* This is part of HarfBuzz, a text shaping library. * This is part of HarfBuzz, a text shaping library.
* *
@ -367,7 +367,7 @@ public:
for (Run *run = mRunHead.nextRun; run;) { for (Run *run = mRunHead.nextRun; run;) {
Run *origRun = run; Run *origRun = run;
run = run->nextRun; run = run->nextRun;
delete origRun; free (origRun);
} }
} }
@ -543,7 +543,7 @@ protected:
// or before it. Usually the first. // or before it. Usually the first.
return; return;
} }
Run *newRun = new Run; Run *newRun = (Run*) malloc (sizeof (Run));
*newRun = *mCurrentRun; *newRun = *mCurrentRun;
@ -575,6 +575,10 @@ protected:
Run mRunHead; Run mRunHead;
}; };
static inline uint16_t hb_uint16_swap (const uint16_t v)
{ return (v >> 8) | (v << 8); }
static inline uint32_t hb_uint32_swap (const uint32_t v)
{ return (hb_uint16_swap(v) << 16) | hb_uint16_swap(v >> 16); }
/* /*
* shaper * shaper
@ -670,8 +674,14 @@ _hb_directwrite_shape(hb_shape_plan_t *shape_plan,
TextAnalysis::Run *runHead; TextAnalysis::Run *runHead;
hr = analysis.GenerateResults(analyzer, &runHead); hr = analysis.GenerateResults(analyzer, &runHead);
if (FAILED(hr)) { #define FAIL(...) \
//NS_WARNING("Analyzer failed to generate results."); HB_STMT_START { \
DEBUG_MSG (DIRECTWRITE, NULL, __VA_ARGS__); \
return false; \
} HB_STMT_END;
if (FAILED (hr)) {
FAIL ("Analyzer failed to generate results.");
return false; return false;
} }
@ -679,19 +689,13 @@ _hb_directwrite_shape(hb_shape_plan_t *shape_plan,
UINT32 actualGlyphs; UINT32 actualGlyphs;
bool backward = HB_DIRECTION_IS_BACKWARD(buffer->props.direction); bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction);
const wchar_t lang[4] = {0}; const wchar_t lang[20] = {0};
if (buffer->props.language != NULL) { if (buffer->props.language != NULL) {
mbstowcs((wchar_t*) lang, hb_language_to_string (buffer->props.language), 4); mbstowcs ((wchar_t*) lang, hb_language_to_string (buffer->props.language), 20);
} }
#define FAIL(...) \
HB_STMT_START { \
DEBUG_MSG (DIRECTWRITE, NULL, __VA_ARGS__); \
return false; \
} HB_STMT_END;
retry_getglyphs: retry_getglyphs:
UINT16* clusters = (UINT16*) malloc (maxGlyphs * sizeof (UINT16)); UINT16* clusters = (UINT16*) malloc (maxGlyphs * sizeof (UINT16));
UINT16* glyphs = (UINT16*) malloc (maxGlyphs * sizeof (UINT16)); UINT16* glyphs = (UINT16*) malloc (maxGlyphs * sizeof (UINT16));
@ -700,10 +704,27 @@ retry_getglyphs:
DWRITE_SHAPING_GLYPH_PROPERTIES* glyphProperties = (DWRITE_SHAPING_GLYPH_PROPERTIES*) DWRITE_SHAPING_GLYPH_PROPERTIES* glyphProperties = (DWRITE_SHAPING_GLYPH_PROPERTIES*)
malloc (maxGlyphs * sizeof (DWRITE_SHAPING_GLYPH_PROPERTIES)); malloc (maxGlyphs * sizeof (DWRITE_SHAPING_GLYPH_PROPERTIES));
hr = analyzer->GetGlyphs(pchars, length, DWRITE_TYPOGRAPHIC_FEATURES dwfeatures;
dwfeatures.featureCount = num_features;
if (num_features != 0)
{
DWRITE_FONT_FEATURE* dwfeatureArray = (DWRITE_FONT_FEATURE*)
malloc (sizeof (DWRITE_FONT_FEATURE) * num_features);
for (unsigned int i = 0; i < num_features; ++i)
{
dwfeatureArray[i].nameTag = (DWRITE_FONT_FEATURE_TAG)
hb_uint32_swap (features[i].tag);
dwfeatureArray[i].parameter = features[i].value;
}
dwfeatures.features = dwfeatureArray;
}
const DWRITE_TYPOGRAPHIC_FEATURES* dwfeaturesArray =
(const DWRITE_TYPOGRAPHIC_FEATURES*) &dwfeatures;
const UINT32 featuresLength[] = {length};
hr = analyzer->GetGlyphs (pchars, length,
fontFace, FALSE, fontFace, FALSE,
backward, backward,
&runHead->mScript, lang, NULL, NULL, NULL, 0, &runHead->mScript, lang, NULL, &dwfeaturesArray, featuresLength, 1,
maxGlyphs, clusters, textProperties, maxGlyphs, clusters, textProperties,
glyphs, glyphProperties, &actualGlyphs); glyphs, glyphProperties, &actualGlyphs);
@ -760,9 +781,9 @@ retry_getglyphs:
backward, backward,
&runHead->mScript, &runHead->mScript,
lang, lang,
NULL, &dwfeaturesArray,
NULL, featuresLength,
0, 1,
advances, advances,
offsets); offsets);
@ -779,7 +800,7 @@ retry_getglyphs:
vis_clusters[i] = -1; vis_clusters[i] = -1;
for (unsigned int i = 0; i < buffer->len; i++) { for (unsigned int i = 0; i < buffer->len; i++) {
uint32_t *p = &vis_clusters[log_clusters[buffer->info[i].utf16_index()]]; uint32_t *p = &vis_clusters[log_clusters[buffer->info[i].utf16_index()]];
//*p = MIN (*p, buffer->info[i].cluster); *p = MIN (*p, buffer->info[i].cluster);
} }
for (unsigned int i = 1; i < actualGlyphs; i++) for (unsigned int i = 1; i < actualGlyphs; i++)
if (vis_clusters[i] == -1) if (vis_clusters[i] == -1)
@ -829,6 +850,7 @@ retry_getglyphs:
free (glyphProperties); free (glyphProperties);
free (advances); free (advances);
free (offsets); free (offsets);
free (dwfeatures.features);
/* Wow, done! */ /* Wow, done! */
return true; return true;