Remove QCoreTextFontEngineMulti

It's not used anymore since we have switch to HarfBuzz on Mac.

Change-Id: I68252fbe3021f54dacac5a901184c3f3e541a6b7
Reviewed-by: Jiang Jiang <jiang.jiang@nokia.com>
Reviewed-by: Morten Johan Sørvig <morten.sorvig@nokia.com>
This commit is contained in:
Jiang Jiang 2011-12-01 11:26:53 +01:00 committed by Qt by Nokia
parent 6887a7e395
commit d05b6b6e95
2 changed files with 0 additions and 357 deletions

View File

@ -77,329 +77,6 @@ static void loadAdvancesForGlyphs(CTFontRef ctfont,
}
}
QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const QCFString &name, const QFontDef &fontDef, bool kerning)
: QFontEngineMulti(0)
{
this->fontDef = fontDef;
CTFontSymbolicTraits symbolicTraits = 0;
if (fontDef.weight >= QFont::Bold)
symbolicTraits |= kCTFontBoldTrait;
switch (fontDef.style) {
case QFont::StyleNormal:
break;
case QFont::StyleItalic:
case QFont::StyleOblique:
symbolicTraits |= kCTFontItalicTrait;
break;
}
transform = CGAffineTransformIdentity;
if (fontDef.stretch != 100) {
transform = CGAffineTransformMakeScale(float(fontDef.stretch) / float(100), 1);
}
QCFType<CTFontDescriptorRef> descriptor = CTFontDescriptorCreateWithNameAndSize(name, fontDef.pixelSize);
QCFType<CTFontRef> baseFont = CTFontCreateWithFontDescriptor(descriptor, fontDef.pixelSize, &transform);
ctfont = NULL;
// There is a side effect in Core Text: if we apply 0 as symbolic traits to a font in normal weight,
// we will get the light version of that font (while the way supposed to work doesn't:
// setting kCTFontWeightTrait to some value between -1.0 to 0.0 has no effect on font selection)
if (fontDef.weight != QFont::Normal || symbolicTraits)
ctfont = CTFontCreateCopyWithSymbolicTraits(baseFont, fontDef.pixelSize, &transform, symbolicTraits, symbolicTraits);
// CTFontCreateCopyWithSymbolicTraits returns NULL if we ask for a trait that does
// not exist for the given font. (for example italic)
if (ctfont == 0) {
ctfont = baseFont;
CFRetain(ctfont);
}
init(kerning);
}
QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(CTFontRef ctFontRef, const QFontDef &fontDef, bool kerning)
: QFontEngineMulti(0)
{
this->fontDef = fontDef;
ctfont = (CTFontRef) CFRetain(ctFontRef);
init(kerning);
}
QCoreTextFontEngineMulti::~QCoreTextFontEngineMulti()
{
CFRelease(ctfont);
}
void QCoreTextFontEngineMulti::init(bool kerning)
{
Q_ASSERT(ctfont != NULL);
attributeDict = CFDictionaryCreateMutable(0, 2,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CFDictionaryAddValue(attributeDict, kCTFontAttributeName, ctfont);
if (!kerning) {
float zero = 0.0;
QCFType<CFNumberRef> noKern = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloatType, &zero);
CFDictionaryAddValue(attributeDict, kCTKernAttributeName, noKern);
}
QCoreTextFontEngine *fe = new QCoreTextFontEngine(ctfont, fontDef);
fontDef.family = fe->fontDef.family;
fontDef.styleName = fe->fontDef.styleName;
transform = fe->transform;
fe->ref.ref();
engines.append(fe);
}
uint QCoreTextFontEngineMulti::fontIndexForFont(CTFontRef font) const
{
for (int i = 0; i < engines.count(); ++i) {
if (CFEqual(engineAt(i)->ctfont, font))
return i;
}
QCoreTextFontEngineMulti *that = const_cast<QCoreTextFontEngineMulti *>(this);
QCoreTextFontEngine *fe = new QCoreTextFontEngine(font, fontDef);
fe->ref.ref();
that->engines.append(fe);
return engines.count() - 1;
}
bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs,
int *nglyphs, QTextEngine::ShaperFlags flags,
unsigned short *logClusters, const HB_CharAttributes *,
QScriptItem *si) const
{
QCFType<CFStringRef> cfstring = CFStringCreateWithCharactersNoCopy(0,
reinterpret_cast<const UniChar *>(str),
len, kCFAllocatorNull);
QCFType<CFAttributedStringRef> attributedString = CFAttributedStringCreate(0, cfstring, attributeDict);
QCFType<CTTypesetterRef> typeSetter;
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
if (flags & QTextEngine::RightToLeft) {
const void *optionKeys[] = { kCTTypesetterOptionForcedEmbeddingLevel };
const short rtlForcedEmbeddingLevelValue = 1;
const void *rtlOptionValues[] = { CFNumberCreate(kCFAllocatorDefault, kCFNumberShortType, &rtlForcedEmbeddingLevelValue) };
QCFType<CFDictionaryRef> options = CFDictionaryCreate(kCFAllocatorDefault, optionKeys, rtlOptionValues, 1,
&kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
typeSetter = CTTypesetterCreateWithAttributedStringAndOptions(attributedString, options);
} else
#else
Q_UNUSED(flags);
#endif
typeSetter = CTTypesetterCreateWithAttributedString(attributedString);
CFRange range = {0, 0};
QCFType<CTLineRef> line = CTTypesetterCreateLine(typeSetter, range);
CFArrayRef array = CTLineGetGlyphRuns(line);
uint arraySize = CFArrayGetCount(array);
glyph_t *outGlyphs = glyphs->glyphs;
HB_GlyphAttributes *outAttributes = glyphs->attributes;
QFixed *outAdvances_x = glyphs->advances_x;
QFixed *outAdvances_y = glyphs->advances_y;
glyph_t *initialGlyph = outGlyphs;
if (arraySize == 0) {
// CoreText failed to shape the text we gave it, so we assume one glyph
// per character and build a list of invalid glyphs with zero advance
*nglyphs = len;
for (int i = 0; i < len; ++i) {
outGlyphs[i] = 0;
if (logClusters)
logClusters[i] = i;
outAdvances_x[i] = QFixed();
outAdvances_y[i] = QFixed();
outAttributes[i].clusterStart = true;
}
return true;
}
const bool rtl = (CTRunGetStatus(static_cast<CTRunRef>(CFArrayGetValueAtIndex(array, 0))) & kCTRunStatusRightToLeft);
bool outOBounds = false;
for (uint i = 0; i < arraySize; ++i) {
CTRunRef run = static_cast<CTRunRef>(CFArrayGetValueAtIndex(array, rtl ? (arraySize - 1 - i) : i));
CFIndex glyphCount = CTRunGetGlyphCount(run);
if (glyphCount == 0)
continue;
Q_ASSERT((CTRunGetStatus(run) & kCTRunStatusRightToLeft) == rtl);
CFRange stringRange = CTRunGetStringRange(run);
int prepend = 0;
#if MAC_OS_X_VERSION_MAX_ALLOWED == MAC_OS_X_VERSION_10_5
UniChar beginGlyph = CFStringGetCharacterAtIndex(cfstring, stringRange.location);
QChar dir = QChar::direction(beginGlyph);
bool beginWithOverride = dir == QChar::DirLRO || dir == QChar::DirRLO || dir == QChar::DirLRE || dir == QChar::DirRLE;
if (beginWithOverride) {
logClusters[stringRange.location] = 0;
outGlyphs[0] = 0xFFFF;
outAdvances_x[0] = 0;
outAdvances_y[0] = 0;
outAttributes[0].clusterStart = true;
outAttributes[0].dontPrint = true;
outGlyphs++;
outAdvances_x++;
outAdvances_y++;
outAttributes++;
prepend = 1;
}
#endif
UniChar endGlyph = CFStringGetCharacterAtIndex(cfstring, stringRange.location + stringRange.length - 1);
bool endWithPDF = QChar::direction(endGlyph) == QChar::DirPDF;
if (endWithPDF)
glyphCount++;
if (!outOBounds && outGlyphs + glyphCount - initialGlyph > *nglyphs) {
outOBounds = true;
}
if (!outOBounds) {
CFDictionaryRef runAttribs = CTRunGetAttributes(run);
//NSLog(@"Dictionary %@", runAttribs);
if (!runAttribs)
runAttribs = attributeDict;
CTFontRef runFont = static_cast<CTFontRef>(CFDictionaryGetValue(runAttribs, kCTFontAttributeName));
uint fontIndex = fontIndexForFont(runFont);
const QFontEngine *engine = engineAt(fontIndex);
fontIndex <<= 24;
si->ascent = qMax(engine->ascent(), si->ascent);
si->descent = qMax(engine->descent(), si->descent);
si->leading = qMax(engine->leading(), si->leading);
//NSLog(@"Run Font Name = %@", CTFontCopyFamilyName(runFont));
if (endWithPDF)
glyphCount--;
QVarLengthArray<CGGlyph, 512> cgglyphs(0);
const CGGlyph *tmpGlyphs = CTRunGetGlyphsPtr(run);
if (!tmpGlyphs) {
cgglyphs.resize(glyphCount);
CTRunGetGlyphs(run, range, cgglyphs.data());
tmpGlyphs = cgglyphs.constData();
}
QVarLengthArray<CGPoint, 512> cgpoints(0);
const CGPoint *tmpPoints = CTRunGetPositionsPtr(run);
if (!tmpPoints) {
cgpoints.resize(glyphCount);
CTRunGetPositions(run, range, cgpoints.data());
tmpPoints = cgpoints.constData();
}
const int rtlOffset = rtl ? (glyphCount - 1) : 0;
const int rtlSign = rtl ? -1 : 1;
if (logClusters) {
CFRange stringRange = CTRunGetStringRange(run);
QVarLengthArray<CFIndex, 512> stringIndices(0);
const CFIndex *tmpIndices = CTRunGetStringIndicesPtr(run);
if (!tmpIndices) {
stringIndices.resize(glyphCount);
CTRunGetStringIndices(run, range, stringIndices.data());
tmpIndices = stringIndices.constData();
}
const int firstGlyphIndex = outGlyphs - initialGlyph;
outAttributes[0].clusterStart = true;
CFIndex k = 0;
CFIndex i = 0;
for (i = stringRange.location + prepend;
(i < stringRange.location + stringRange.length) && (k < glyphCount); ++i) {
if (tmpIndices[k * rtlSign + rtlOffset] == i || i == stringRange.location + prepend) {
logClusters[i] = k + firstGlyphIndex;
outAttributes[k].clusterStart = true;
++k;
} else {
logClusters[i] = k + firstGlyphIndex - 1;
}
}
// in case of a ligature at the end, fill the remaining logcluster entries
for (;i < stringRange.location + stringRange.length; i++) {
logClusters[i] = k + firstGlyphIndex - 1;
}
}
for (CFIndex i = 0; i < glyphCount - 1; ++i) {
int idx = rtlOffset + rtlSign * i;
outGlyphs[idx] = tmpGlyphs[i] | fontIndex;
outAdvances_x[idx] = QFixed::fromReal(tmpPoints[i + 1].x - tmpPoints[i].x);
// Use negative y advance for flipped coordinate system
outAdvances_y[idx] = QFixed::fromReal(tmpPoints[i].y - tmpPoints[i + 1].y);
if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
outAdvances_x[idx] = outAdvances_x[idx].round();
outAdvances_y[idx] = outAdvances_y[idx].round();
}
}
CGSize lastGlyphAdvance;
CTFontGetAdvancesForGlyphs(runFont, kCTFontHorizontalOrientation, tmpGlyphs + glyphCount - 1, &lastGlyphAdvance, 1);
outGlyphs[rtl ? 0 : (glyphCount - 1)] = tmpGlyphs[glyphCount - 1] | fontIndex;
outAdvances_x[rtl ? 0 : (glyphCount - 1)] =
(fontDef.styleStrategy & QFont::ForceIntegerMetrics)
? QFixed::fromReal(lastGlyphAdvance.width).round()
: QFixed::fromReal(lastGlyphAdvance.width);
if (endWithPDF) {
logClusters[stringRange.location + stringRange.length - 1] = glyphCount + prepend;
outGlyphs[glyphCount] = 0xFFFF;
outAdvances_x[glyphCount] = 0;
outAdvances_y[glyphCount] = 0;
outAttributes[glyphCount].clusterStart = true;
outAttributes[glyphCount].dontPrint = true;
glyphCount++;
}
}
outGlyphs += glyphCount;
outAttributes += glyphCount;
outAdvances_x += glyphCount;
outAdvances_y += glyphCount;
}
*nglyphs = (outGlyphs - initialGlyph);
return !outOBounds;
}
bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs,
int *nglyphs, QTextEngine::ShaperFlags flags) const
{
*nglyphs = len;
QCFType<CFStringRef> cfstring;
QVarLengthArray<CGGlyph> cgGlyphs(len);
CTFontGetGlyphsForCharacters(ctfont, (const UniChar*)str, cgGlyphs.data(), len);
for (int i = 0; i < len; ++i) {
if (cgGlyphs[i]) {
glyphs->glyphs[i] = cgGlyphs[i];
} else {
if (!cfstring)
cfstring = CFStringCreateWithCharactersNoCopy(0, reinterpret_cast<const UniChar *>(str), len, kCFAllocatorNull);
QCFType<CTFontRef> substituteFont = CTFontCreateForString(ctfont, cfstring, CFRangeMake(i, 1));
CGGlyph substituteGlyph = 0;
CTFontGetGlyphsForCharacters(substituteFont, (const UniChar*)str + i, &substituteGlyph, 1);
if (substituteGlyph) {
const uint fontIndex = (fontIndexForFont(substituteFont) << 24);
glyphs->glyphs[i] = substituteGlyph | fontIndex;
if (!(flags & QTextEngine::GlyphIndicesOnly)) {
CGSize advance;
CTFontGetAdvancesForGlyphs(substituteFont, kCTFontHorizontalOrientation, &substituteGlyph, &advance, 1);
glyphs->advances_x[i] = QFixed::fromReal(advance.width);
glyphs->advances_y[i] = QFixed::fromReal(advance.height);
}
}
}
}
if (flags & QTextEngine::GlyphIndicesOnly)
return true;
loadAdvancesForGlyphs(ctfont, cgGlyphs, glyphs, len, flags, fontDef);
return true;
}
void QCoreTextFontEngineMulti::loadEngine(int)
{
// Do nothing
Q_ASSERT(false);
}
extern int qt_antialiasing_threshold, qt_enable_font_smoothing;
CGAffineTransform qt_transform_from_fontdef(const QFontDef &fontDef)

View File

@ -53,7 +53,6 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
class QRawFontPrivate;
class QCoreTextFontEngineMulti;
class QCoreTextFontEngine : public QFontEngine
{
public:
@ -109,39 +108,6 @@ private:
int synthesisFlags;
CGAffineTransform transform;
QFixed avgCharWidth;
friend class QCoreTextFontEngineMulti;
};
class QCoreTextFontEngineMulti : public QFontEngineMulti
{
public:
QCoreTextFontEngineMulti(const QCFString &name, const QFontDef &fontDef, bool kerning);
QCoreTextFontEngineMulti(CTFontRef ctFontRef, const QFontDef &fontDef, bool kerning);
~QCoreTextFontEngineMulti();
virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs,
QTextEngine::ShaperFlags flags) const;
bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs,
QTextEngine::ShaperFlags flags,
unsigned short *logClusters, const HB_CharAttributes *charAttributes,
QScriptItem *si) const;
virtual const char *name() const { return "CoreText"; }
inline CTFontRef macFontID() const { return ctfont; }
protected:
virtual void loadEngine(int at);
private:
void init(bool kerning);
inline const QCoreTextFontEngine *engineAt(int i) const
{ return static_cast<const QCoreTextFontEngine *>(engines.at(i)); }
uint fontIndexForFont(CTFontRef font) const;
CTFontRef ctfont;
mutable QCFType<CFMutableDictionaryRef> attributeDict;
CGAffineTransform transform;
friend class QFontDialogPrivate;
};
CGAffineTransform qt_transform_from_fontdef(const QFontDef &fontDef);