[dwrite] minor
This commit is contained in:
parent
ebccd01974
commit
fe18c471a4
|
@ -1,8 +1,9 @@
|
|||
#!/bin/bash
|
||||
# Suggested setup to use the script:
|
||||
# (on the root of the project)
|
||||
# $ NOCONFIGURE=1 ./autogen.sh --with-freetype --with-glib --with-gobject --with-cairo
|
||||
# $ mkdir build && cd build && ../configure && make -j5 && cd ..
|
||||
# $ NOCONFIGURE=1 ./autogen.sh && mkdir build && cd build
|
||||
# $ ../configure --with-freetype --with-glib --with-gobject --with-cairo
|
||||
# $ make -j5 && cd ..
|
||||
# $ src/dev-run.sh [FONT-FILE] [TEXT]
|
||||
#
|
||||
# Or, using cmake:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* Copyright © 2015-2018 Ebrahim Byagowi
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
|
@ -71,7 +71,7 @@ public:
|
|||
|
||||
// IDWriteFontFileLoader methods
|
||||
virtual HRESULT STDMETHODCALLTYPE CreateStreamFromKey (void const* fontFileReferenceKey,
|
||||
UINT32 fontFileReferenceKeySize,
|
||||
uint32_t fontFileReferenceKeySize,
|
||||
OUT IDWriteFontFileStream** fontFileStream)
|
||||
{
|
||||
*fontFileStream = mFontFileStream;
|
||||
|
@ -103,9 +103,8 @@ public:
|
|||
OUT void** fragmentContext)
|
||||
{
|
||||
// We are required to do bounds checking.
|
||||
if (fileOffset + fragmentSize > mSize) {
|
||||
if (fileOffset + fragmentSize > mSize)
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// truncate the 64 bit fileOffset to size_t sized index into mData
|
||||
size_t index = static_cast<size_t> (fileOffset);
|
||||
|
@ -135,7 +134,8 @@ public:
|
|||
* shaper face data
|
||||
*/
|
||||
|
||||
struct hb_directwrite_shaper_face_data_t {
|
||||
struct hb_directwrite_shaper_face_data_t
|
||||
{
|
||||
IDWriteFactory *dwriteFactory;
|
||||
IDWriteFontFile *fontFile;
|
||||
IDWriteFontFileStream *fontFileStream;
|
||||
|
@ -179,20 +179,16 @@ _hb_directwrite_shaper_face_data_create (hb_face_t *face)
|
|||
return nullptr; \
|
||||
} HB_STMT_END;
|
||||
|
||||
if (FAILED (hr)) {
|
||||
if (FAILED (hr))
|
||||
FAIL ("Failed to load font file from data!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
BOOL isSupported;
|
||||
DWRITE_FONT_FILE_TYPE fileType;
|
||||
DWRITE_FONT_FACE_TYPE faceType;
|
||||
UINT32 numberOfFaces;
|
||||
uint32_t numberOfFaces;
|
||||
hr = fontFile->Analyze (&isSupported, &fileType, &faceType, &numberOfFaces);
|
||||
if (FAILED (hr) || !isSupported) {
|
||||
if (FAILED (hr) || !isSupported)
|
||||
FAIL ("Font file is not supported.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#undef FAIL
|
||||
|
||||
|
@ -217,7 +213,8 @@ _hb_directwrite_shaper_face_data_destroy (hb_directwrite_shaper_face_data_t *dat
|
|||
data->fontFace->Release ();
|
||||
if (data->fontFile)
|
||||
data->fontFile->Release ();
|
||||
if (data->dwriteFactory) {
|
||||
if (data->dwriteFactory)
|
||||
{
|
||||
if (data->fontFileLoader)
|
||||
data->dwriteFactory->UnregisterFontFileLoader (data->fontFileLoader);
|
||||
data->dwriteFactory->Release ();
|
||||
|
@ -237,7 +234,8 @@ _hb_directwrite_shaper_face_data_destroy (hb_directwrite_shaper_face_data_t *dat
|
|||
* shaper font data
|
||||
*/
|
||||
|
||||
struct hb_directwrite_shaper_font_data_t {
|
||||
struct hb_directwrite_shaper_font_data_t
|
||||
{
|
||||
};
|
||||
|
||||
hb_directwrite_shaper_font_data_t *
|
||||
|
@ -324,9 +322,11 @@ public:
|
|||
, mReadingDirection (readingDirection)
|
||||
, mCurrentRun (nullptr) { };
|
||||
|
||||
~TextAnalysis () {
|
||||
~TextAnalysis ()
|
||||
{
|
||||
// delete runs, except mRunHead which is part of the TextAnalysis object
|
||||
for (Run *run = mRunHead.nextRun; run;) {
|
||||
for (Run *run = mRunHead.nextRun; run;)
|
||||
{
|
||||
Run *origRun = run;
|
||||
run = run->nextRun;
|
||||
delete origRun;
|
||||
|
@ -334,7 +334,8 @@ public:
|
|||
}
|
||||
|
||||
STDMETHODIMP GenerateResults (IDWriteTextAnalyzer* textAnalyzer,
|
||||
Run **runHead) {
|
||||
Run **runHead)
|
||||
{
|
||||
// Analyzes the text using the script analyzer and returns
|
||||
// the result as a series of runs.
|
||||
|
||||
|
@ -350,9 +351,8 @@ public:
|
|||
mCurrentRun = &mRunHead;
|
||||
|
||||
// Call each of the analyzers in sequence, recording their results.
|
||||
if (SUCCEEDED (hr = textAnalyzer->AnalyzeScript (this, 0, mTextLength, this))) {
|
||||
if (SUCCEEDED (hr = textAnalyzer->AnalyzeScript (this, 0, mTextLength, this)))
|
||||
*runHead = &mRunHead;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
@ -363,12 +363,14 @@ public:
|
|||
OUT wchar_t const** textString,
|
||||
OUT uint32_t* textLength)
|
||||
{
|
||||
if (textPosition >= mTextLength) {
|
||||
if (textPosition >= mTextLength)
|
||||
{
|
||||
// No text at this position, valid query though.
|
||||
*textString = nullptr;
|
||||
*textLength = 0;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
*textString = mText + textPosition;
|
||||
*textLength = mTextLength - textPosition;
|
||||
}
|
||||
|
@ -379,13 +381,15 @@ public:
|
|||
OUT wchar_t const** textString,
|
||||
OUT uint32_t* textLength)
|
||||
{
|
||||
if (textPosition == 0 || textPosition > mTextLength) {
|
||||
if (textPosition == 0 || textPosition > mTextLength)
|
||||
{
|
||||
// Either there is no text before here (== 0), or this
|
||||
// is an invalid position. The query is considered valid though.
|
||||
*textString = nullptr;
|
||||
*textLength = 0;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
*textString = mText;
|
||||
*textLength = textPosition;
|
||||
}
|
||||
|
@ -458,14 +462,10 @@ protected:
|
|||
// Split the tail if needed (the length remaining is less than the
|
||||
// current run's size).
|
||||
if (*textLength < mCurrentRun->mTextLength)
|
||||
{
|
||||
SplitCurrentRun (mCurrentRun->mTextStart + *textLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just advance the current run.
|
||||
mCurrentRun = mCurrentRun->nextRun;
|
||||
}
|
||||
*textLength -= origRun->mTextLength;
|
||||
|
||||
// Return a reference to the run that was just current.
|
||||
|
@ -480,17 +480,14 @@ protected:
|
|||
// corresponding run for the text position.
|
||||
|
||||
if (mCurrentRun && mCurrentRun->ContainsTextPosition (textPosition))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (Run *run = &mRunHead; run; run = run->nextRun) {
|
||||
for (Run *run = &mRunHead; run; run = run->nextRun)
|
||||
if (run->ContainsTextPosition (textPosition))
|
||||
{
|
||||
mCurrentRun = run;
|
||||
return;
|
||||
}
|
||||
}
|
||||
//NS_NOTREACHED ("We should always be able to find the text position in one \
|
||||
// of our runs");
|
||||
}
|
||||
|
@ -592,15 +589,14 @@ _hb_directwrite_shape_full (hb_shape_plan_t *shape_plan,
|
|||
textString[chars_len++] = c;
|
||||
else if (unlikely (c > 0x10FFFFu))
|
||||
textString[chars_len++] = 0xFFFDu;
|
||||
else {
|
||||
else
|
||||
{
|
||||
textString[chars_len++] = 0xD800u + ((c - 0x10000u) >> 10);
|
||||
textString[chars_len++] = 0xDC00u + ((c - 0x10000u) & ((1u << 10) - 1));
|
||||
}
|
||||
}
|
||||
|
||||
ALLOCATE_ARRAY (WORD, log_clusters, chars_len);
|
||||
// if (num_features)
|
||||
{
|
||||
/* Need log_clusters to assign features. */
|
||||
chars_len = 0;
|
||||
for (unsigned int i = 0; i < buffer->len; i++)
|
||||
|
@ -611,7 +607,6 @@ _hb_directwrite_shape_full (hb_shape_plan_t *shape_plan,
|
|||
if (hb_in_range (c, 0x10000u, 0x10FFFFu))
|
||||
log_clusters[chars_len++] = cluster; /* Surrogates. */
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Handle TEST_DISABLE_OPTIONAL_LIGATURES
|
||||
|
||||
|
@ -638,10 +633,7 @@ _hb_directwrite_shape_full (hb_shape_plan_t *shape_plan,
|
|||
} HB_STMT_END;
|
||||
|
||||
if (FAILED (hr))
|
||||
{
|
||||
FAIL ("Analyzer failed to generate results.");
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t maxGlyphCount = 3 * textLength / 2 + 16;
|
||||
uint32_t glyphCount;
|
||||
|
@ -654,21 +646,23 @@ _hb_directwrite_shape_full (hb_shape_plan_t *shape_plan,
|
|||
hb_language_to_string (buffer->props.language), 20);
|
||||
}
|
||||
|
||||
DWRITE_TYPOGRAPHIC_FEATURES singleFeatures;
|
||||
singleFeatures.featureCount = num_features;
|
||||
// TODO: it does work but doesn't care about ranges
|
||||
DWRITE_TYPOGRAPHIC_FEATURES typographic_features;
|
||||
typographic_features.featureCount = num_features;
|
||||
if (num_features)
|
||||
{
|
||||
singleFeatures.features = new DWRITE_FONT_FEATURE[num_features];
|
||||
typographic_features.features = new DWRITE_FONT_FEATURE[num_features];
|
||||
for (unsigned int i = 0; i < num_features; ++i)
|
||||
{
|
||||
singleFeatures.features[i].nameTag = (DWRITE_FONT_FEATURE_TAG)
|
||||
typographic_features.features[i].nameTag = (DWRITE_FONT_FEATURE_TAG)
|
||||
hb_uint32_swap (features[i].tag);
|
||||
singleFeatures.features[i].parameter = features[i].value;
|
||||
typographic_features.features[i].parameter = features[i].value;
|
||||
}
|
||||
}
|
||||
const DWRITE_TYPOGRAPHIC_FEATURES* dwFeatures =
|
||||
(const DWRITE_TYPOGRAPHIC_FEATURES*) &singleFeatures;
|
||||
(const DWRITE_TYPOGRAPHIC_FEATURES*) &typographic_features;
|
||||
const uint32_t featureRangeLengths[] = { textLength };
|
||||
//
|
||||
|
||||
uint16_t* clusterMap = new uint16_t[textLength];
|
||||
DWRITE_SHAPING_TEXT_PROPERTIES* textProperties =
|
||||
|
@ -693,10 +687,7 @@ retry_getglyphs:
|
|||
goto retry_getglyphs;
|
||||
}
|
||||
if (FAILED (hr))
|
||||
{
|
||||
FAIL ("Analyzer failed to get glyphs.");
|
||||
return false;
|
||||
}
|
||||
|
||||
float* glyphAdvances = new float[maxGlyphCount];
|
||||
DWRITE_GLYPH_OFFSET* glyphOffsets = new DWRITE_GLYPH_OFFSET[maxGlyphCount];
|
||||
|
@ -730,10 +721,7 @@ retry_getglyphs:
|
|||
glyphAdvances, glyphOffsets);
|
||||
|
||||
if (FAILED (hr))
|
||||
{
|
||||
FAIL ("Analyzer failed to get glyph placements.");
|
||||
return false;
|
||||
}
|
||||
|
||||
IDWriteTextAnalyzer1* analyzer1;
|
||||
analyzer->QueryInterface (&analyzer1);
|
||||
|
@ -748,10 +736,7 @@ retry_getglyphs:
|
|||
glyphProperties, justificationOpportunities);
|
||||
|
||||
if (FAILED (hr))
|
||||
{
|
||||
FAIL ("Analyzer failed to get justification opportunities.");
|
||||
return false;
|
||||
}
|
||||
|
||||
float* justifiedGlyphAdvances = new float[maxGlyphCount];
|
||||
DWRITE_GLYPH_OFFSET* justifiedGlyphOffsets = new DWRITE_GLYPH_OFFSET[glyphCount];
|
||||
|
@ -759,18 +744,12 @@ retry_getglyphs:
|
|||
glyphAdvances, glyphOffsets, justifiedGlyphAdvances, justifiedGlyphOffsets);
|
||||
|
||||
if (FAILED (hr))
|
||||
{
|
||||
FAIL ("Analyzer failed to get justified glyph advances.");
|
||||
return false;
|
||||
}
|
||||
|
||||
DWRITE_SCRIPT_PROPERTIES scriptProperties;
|
||||
hr = analyzer1->GetScriptProperties (runHead->mScript, &scriptProperties);
|
||||
if (FAILED (hr))
|
||||
{
|
||||
FAIL ("Analyzer failed to get script properties.");
|
||||
return false;
|
||||
}
|
||||
uint32_t justificationCharacter = scriptProperties.justificationCharacter;
|
||||
|
||||
// if a script justificationCharacter is not space, it can have GetJustifiedGlyphs
|
||||
|
@ -801,10 +780,7 @@ retry_getglyphs:
|
|||
goto retry_getjustifiedglyphs;
|
||||
}
|
||||
if (FAILED (hr))
|
||||
{
|
||||
FAIL ("Analyzer failed to get justified glyphs.");
|
||||
return false;
|
||||
}
|
||||
|
||||
delete [] clusterMap;
|
||||
delete [] glyphIndices;
|
||||
|
@ -896,7 +872,7 @@ retry_getglyphs:
|
|||
delete [] glyphOffsets;
|
||||
|
||||
if (num_features)
|
||||
delete [] singleFeatures.features;
|
||||
delete [] typographic_features.features;
|
||||
|
||||
/* Wow, done! */
|
||||
return true;
|
||||
|
|
Loading…
Reference in New Issue