6#include <qpa/qplatformfontdatabase.h>
7#include <QtCore/qendian.h>
9#include <QtCore/qsettings.h>
11#include <QtCore/qoperatingsystemversion.h>
12#include <QtGui/qpainterpath.h>
13#include <private/qcoregraphics_p.h>
14#include <private/qimage_p.h>
18#if defined(Q_OS_MACOS)
22#if defined(QT_PLATFORM_UIKIT)
23#import <UIKit/UIKit.h>
29#if defined(Q_OS_MACOS)
30#define kCTFontWeightUltraLight NSFontWeightUltraLight
31#define kCTFontWeightThin NSFontWeightThin
32#define kCTFontWeightLight NSFontWeightLight
33#define kCTFontWeightRegular NSFontWeightRegular
34#define kCTFontWeightMedium NSFontWeightMedium
35#define kCTFontWeightSemibold NSFontWeightSemibold
36#define kCTFontWeightBold NSFontWeightBold
37#define kCTFontWeightHeavy NSFontWeightHeavy
38#define kCTFontWeightBlack NSFontWeightBlack
39#elif defined(QT_PLATFORM_UIKIT)
40#define kCTFontWeightUltraLight UIFontWeightUltraLight
41#define kCTFontWeightThin UIFontWeightThin
42#define kCTFontWeightLight UIFontWeightLight
43#define kCTFontWeightRegular UIFontWeightRegular
44#define kCTFontWeightMedium UIFontWeightMedium
45#define kCTFontWeightSemibold UIFontWeightSemibold
46#define kCTFontWeightBold UIFontWeightBold
47#define kCTFontWeightHeavy UIFontWeightHeavy
48#define kCTFontWeightBlack UIFontWeightBlack
63 CFIndex tableLength = CFDataGetLength(
table);
65 CFDataGetBytes(
table, CFRangeMake(0, tableLength),
buffer);
73#define COMPARE_WEIGHT_DISTANCE(ct_weight, qt_weight) \
76 if ((d = qAbs(value - ct_weight)) < distance) { \
96#undef COMPARE_WEIGHT_DISTANCE
103 CGAffineTransform
transform = CGAffineTransformIdentity;
105 transform = CGAffineTransformMakeScale(
float(fontDef.
stretch) /
float(100), 1);
144 qWarning(
"QCoreTextFontEngine::create: CGFontCreateWithDataProvider failed");
158 cgFont = CTFontCopyGraphicsFont(
font,
nullptr);
193 QCFString styleName = (CFStringRef) CTFontCopyAttribute(
ctfont, kCTFontStyleNameAttribute);
197 CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(
ctfont);
199 if (traits & kCTFontColorGlyphsTrait)
206 if (traits & kCTFontItalicTrait)
209 static const auto getTraitValue = [](CFDictionaryRef allTraits, CFStringRef trait) ->
float {
210 if (CFDictionaryContainsKey(allTraits, trait)) {
211 CFNumberRef traitNum = (CFNumberRef) CFDictionaryGetValue(allTraits, trait);
213 CFNumberGetValue(traitNum, kCFNumberFloatType, &
v);
220 int slant =
static_cast<int>(getTraitValue(allTraits, kCTFontSlantTrait) * 500 + 500);
221 if (slant > 500 && !(traits & kCTFontItalicTrait))
234 unsigned emSize = CTFontGetUnitsPerEm(
ctfont);
235 if (os2Table.
size() >= 10) {
263 CGGlyph glyphIndices[2];
265 CTFontGetGlyphsForCharacters(
ctfont, (
const UniChar *)
str, glyphIndices,
len);
267 return glyphIndices[0];
271 int *nglyphs, QFontEngine::ShaperFlags
flags)
const
274 if (*nglyphs <
len) {
280 CTFontGetGlyphsForCharacters(
ctfont, (
const UniChar*)
str, cgGlyphs.
data(),
len);
283 for (
int i = 0;
i <
len; ++
i) {
284 glyphs->
glyphs[glyph_pos] = cgGlyphs[
i];
286 cgGlyphs[glyph_pos] = cgGlyphs[
i];
291 if (
str[
i].isHighSurrogate() &&
i <
len-1 &&
str[
i+1].isLowSurrogate())
295 *nglyphs = glyph_pos;
308 CGRect
rect = CTFontGetBoundingRectsForGlyphs(
ctfont, kCTFontOrientationHorizontal, &
g, 0, 1);
317 CTFontGetAdvancesForGlyphs(
ctfont, kCTFontOrientationHorizontal, &
g, advances, 1);
373 if (glyphs.
size() == 0)
378 CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(
ctx);
380 CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, -1, 0, -paintDeviceHeight);
383 Q_UNUSED(CGAffineTransformConcat(cgMatrix, oldTextMatrix));
386 cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -
SYNTHETIC_ITALIC_SKEW, 1, 0, 0));
388 cgMatrix = CGAffineTransformConcat(cgMatrix,
transform);
390 CGContextSetTextMatrix(
ctx, cgMatrix);
392 CGContextSetTextDrawingMode(
ctx, kCGTextFill);
398 for (
int i = 0;
i < glyphs.
size(); ++
i) {
399 cgPositions[
i].x =
positions[
i].x.toReal() - firstX;
400 cgPositions[
i].y = firstY -
positions[
i].y.toReal();
401 cgGlyphs[
i] = glyphs[
i];
410 QTransform matrix(cgMatrix.a, cgMatrix.b, cgMatrix.c, cgMatrix.d, cgMatrix.tx, cgMatrix.ty);
417 CGContextSetTextPosition(
ctx,
423 CGContextSetTextMatrix(
ctx, oldTextMatrix);
438 switch(element->type) {
439 case kCGPathElementMoveToPoint:
441 element->points[0].y + myInfo->
pos.
y());
443 case kCGPathElementAddLineToPoint:
445 element->points[0].y + myInfo->
pos.
y());
447 case kCGPathElementAddQuadCurveToPoint:
449 element->points[0].y + myInfo->
pos.
y(),
450 (element->points[1].x * myInfo->
stretch) + myInfo->
pos.
x(),
451 element->points[1].y + myInfo->
pos.
y());
453 case kCGPathElementAddCurveToPoint:
455 element->points[0].y + myInfo->
pos.
y(),
456 (element->points[1].x * myInfo->
stretch) + myInfo->
pos.
x(),
457 element->points[1].y + myInfo->
pos.
y(),
458 (element->points[2].x * myInfo->
stretch) + myInfo->
pos.
x(),
459 element->points[2].y + myInfo->
pos.
y());
461 case kCGPathElementCloseSubpath:
465 qCWarning(lcQpaFonts) <<
"Unhandled path transform type: " << element->type;
476 CGAffineTransform cgMatrix = CGAffineTransformIdentity;
477 cgMatrix = CGAffineTransformScale(cgMatrix, 1, -1);
480 cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -
SYNTHETIC_ITALIC_SKEW, 1, 0, 0));
483 for (
int i = 0;
i < nGlyphs; ++
i) {
602 static const int kSize = 10;
605 UniChar character(
'X'); CGGlyph glyph;
606 CTFontGetGlyphsForCharacters(
font, &character, &glyph, 1);
608 auto drawGlyph = [&](
bool smooth) ->
QImage {
613 CGContextSetTextDrawingMode(
ctx, kCGTextFill);
614 CGContextSetGrayFillColor(
ctx, 1, 1);
618 CGContextSetShouldSmoothFonts(
ctx, smooth);
620 CTFontDrawGlyphs(
font, &glyph, &CGPointZero, 1,
ctx);
624 QImage nonSmoothed = drawGlyph(
false);
625 QImage smoothed = drawGlyph(
true);
629 for (
int x = 0;
x < kSize; ++
x) {
630 for (
int y = 0;
y < kSize; ++
y) {
643 auto defaults = [NSUserDefaults standardUserDefaults];
644 qCDebug(lcQpaFonts) <<
"Resolved font smoothing algorithm. Defaults ="
645 << [[
defaults dictionaryRepresentation] dictionaryWithValuesForKeys:@[
646 @"AppleFontSmoothing",
647 @"CGFontRenderingFontSmoothingDisabled"
653 return cachedFontSmoothing;
706 CGContextSetShouldSmoothFonts(
ctx, shouldSmooth);
708#if defined(Q_OS_MACOS)
709 auto glyphColor = [&] {
721 if (!qt_mac_applicationIsInDarkMode())
722 return kCGColorBlack;
724 return kCGColorWhite;
727 const bool blackOnWhiteGlyphs = glyphColor == kCGColorBlack;
728 if (blackOnWhiteGlyphs)
736 CGAffineTransform cgMatrix = CGAffineTransformIdentity;
739 cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0,
SYNTHETIC_ITALIC_SKEW, 1, 0, 0));
742 cgMatrix = CGAffineTransformConcat(cgMatrix,
transform);
745 cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMakeScale(
matrix.m11(),
matrix.m22()));
747 CGGlyph cgGlyph = glyph;
753 CGContextSetTextMatrix(
ctx, cgMatrix);
754#if defined(Q_OS_MACOS)
755 CGContextSetFillColorWithColor(
ctx, CGColorGetConstantColor(glyphColor));
757 CGContextSetRGBFillColor(
ctx, 1, 1, 1, 1);
759 CGContextSetTextDrawingMode(
ctx, kCGTextFill);
760 CGContextSetTextPosition(
ctx, pos_x, pos_y);
762 CTFontDrawGlyphs(
ctfont, &cgGlyph, &CGPointZero, 1,
ctx);
771 CGContextSetTextPosition(
ctx, pos_x + boldOffset, pos_y);
772 CTFontDrawGlyphs(
ctfont, &cgGlyph, &CGPointZero, 1,
ctx);
780 CGContextTranslateCTM(
ctx, pos_x, pos_y);
781 CGContextConcatCTM(
ctx, cgMatrix);
785 CTFontDrawGlyphs(
ctfont, &cgGlyph, &CGPointZero, 1,
ctx);
791#if defined(Q_OS_MACOS)
792 if (blackOnWhiteGlyphs)
876 return CTFontGetGlyphsForCharacters(
ctfont, (
const UniChar *)
string, cgGlyphs.
data(),
len);
886 CGAffineTransform cgMatrix = CGAffineTransformIdentity;
890 cgMatrix = CGAffineTransformScale(cgMatrix,
scale, -
scale);
951 psName = CTFontCopyPostScriptName(
ctfont);
952 copyright = CTFontCopyName(
ctfont, kCTFontCopyrightNameKey);
953 result.postscriptName = QString::fromCFString(psName).toUtf8();
954 result.copyright = QString::fromCFString(copyright).toUtf8();
959 CGRect cgRect = CTFontGetBoundingBox(
ctfont);
962 cgRect.size.width *
scale,
963 cgRect.size.height *
scale);
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
static QCFType constructFromGet(const T &t)
static constexpr bool requiresSurrogates(char32_t ucs4) noexcept
Returns true if the UCS-4-encoded character specified by ucs4 can be split into the high and low part...
static constexpr char16_t highSurrogate(char32_t ucs4) noexcept
Returns the high surrogate part of a UCS-4-encoded code point.
static constexpr char16_t lowSurrogate(char32_t ucs4) noexcept
Returns the low surrogate part of a UCS-4-encoded code point.
The QColor class provides colors based on RGB, HSV or CMYK values.
bool canRender(const QChar *string, int len) const override
Qt::HANDLE handle() const override
glyph_t glyphIndex(uint ucs4) const override
void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int numGlyphs, QPainterPath *path, QTextItem::RenderFlags) override
static qreal fontSmoothingGamma()
QCFType< CTFontRef > ctfont
QFixed emSquareSize() const override
QFixed capHeight() const override
QImage alphaMapForGlyph(glyph_t, const QFixedPoint &subPixelPosition) override
static FontSmoothing fontSmoothing()
void loadAdvancesForGlyphs(QVarLengthArray< CGGlyph > &cgGlyphs, QGlyphLayout *glyphs) const
QFixed averageCharWidth() const override
QImage imageForGlyph(glyph_t glyph, const QFixedPoint &subPixelPosition, const QTransform &m, const QColor &color=QColor())
glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, const QFixedPoint &, const QTransform &matrix, GlyphFormat) override
QFixed underlineThickness
bool getSfntTableData(uint, uchar *, uint *) const override
Returns true if the font table idetified by tag exists in the font; returns false otherwise.
QImage alphaRGBMapForGlyph(glyph_t, const QFixedPoint &subPixelPosition, const QTransform &t) override
QFixed lineThickness() const override
void initializeHeightMetrics() const override
QCoreTextFontEngine(CTFontRef font, const QFontDef &def)
static bool ct_getSfntTable(void *user_data, uint tag, uchar *buffer, uint *length)
static QCoreTextFontEngine * create(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference)
QFontEngine::FaceId face_id
QCFType< CGFontRef > cgFont
bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, ShaperFlags flags) const override
void draw(CGContextRef ctx, qreal x, qreal y, const QTextItemInt &ti, int paintDeviceHeight)
static QFont::Weight qtWeightFromCFWeight(float value)
qreal maxCharWidth() const override
glyph_metrics_t boundingBox(glyph_t glyph) override
bool supportsTransformation(const QTransform &transform) const override
void recalcAdvances(QGlyphLayout *, ShaperFlags) const override
bool expectsGammaCorrectedBlending() const override
FaceId faceId() const override
bool hasColorGlyphs() const
QFontEngine::Properties properties() const override
QFixed underlinePosition() const override
bool shouldAntialias() const
void doKerning(QGlyphLayout *g, ShaperFlags flags) const override
void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics) override
bool shouldSmoothFont() const
QFixed xHeight() const override
QFontEngine * cloneWithSize(qreal pixelSize) const override
QImage bitmapForGlyph(glyph_t, const QFixedPoint &subPixelPosition, const QTransform &t, const QColor &color) override
static uchar highByte(glyph_t glyph)
void loadKerningPairs(QFixed scalingFactor)
QFixed calculatedCapHeight() const
virtual QImage bitmapForGlyph(glyph_t, const QFixedPoint &subPixelPosition, const QTransform &t, const QColor &color=QColor())
virtual glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, const QFixedPoint &, const QTransform &matrix, GlyphFormat)
bool m_heightMetricsQueried
virtual QImage alphaMapForGlyph(glyph_t)
virtual QImage alphaRGBMapForGlyph(glyph_t, const QFixedPoint &subPixelPosition, const QTransform &t)
QByteArray getSfntTable(uint tag) const
virtual QFixed averageCharWidth() const
virtual void doKerning(QGlyphLayout *, ShaperFlags) const
void getGlyphPositions(const QGlyphLayout &glyphs, const QTransform &matrix, QTextItem::RenderFlags flags, QVarLengthArray< glyph_t > &glyphs_out, QVarLengthArray< QFixedPoint > &positions)
Weight
Qt uses a weighting scale from 1 to 1000 compatible with OpenType.
qsizetype bytesPerLine() const
Returns the number of bytes per image scanline.
uchar * scanLine(int)
Returns a pointer to the pixel data at the scanline with index i.
QRgb pixel(int x, int y) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
int width() const
Returns the width of the image.
uchar * bits()
Returns a pointer to the first pixel data.
int height() const
Returns the height of the image.
Format
The following image formats are available in Qt.
@ Format_ARGB32_Premultiplied
void fill(uint pixel)
Fills the entire image with the given pixelValue.
void invertPixels(InvertMode=InvertRgb)
Inverts all pixel values in the image.
void quadTo(const QPointF &ctrlPt, const QPointF &endPt)
Adds a quadratic Bezier curve between the current position and the given endPoint with the control po...
void moveTo(const QPointF &p)
Moves the current point to the given point, implicitly starting a new subpath and closing the previou...
void closeSubpath()
Closes the current subpath by drawing a line to the beginning of the subpath, automatically starting ...
void lineTo(const QPointF &p)
Adds a straight line from the current position to the given endPoint.
void cubicTo(const QPointF &ctrlPt1, const QPointF &ctrlPt2, const QPointF &endPt)
Adds a cubic Bezier curve between the current position and the given endPoint using the control point...
\inmodule QtCore\reentrant
constexpr qreal x() const noexcept
Returns the x coordinate of this point.
constexpr qreal y() const noexcept
Returns the y coordinate of this point.
\inmodule QtCore\reentrant
constexpr size_type size() const noexcept
Combined button and popup list for selecting options.
AudioChannelLayoutTag tag
QT_USE_NAMESPACE QT_BEGIN_NAMESPACE CGBitmapInfo qt_mac_bitmapInfoForImage(const QImage &image)
static const QCssKnownValue positions[NumKnownPositionModes - 1]
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void * user_data
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
Q_GUI_EXPORT int qt_defaultDpi()
static QT_BEGIN_NAMESPACE float SYNTHETIC_ITALIC_SKEW
CGAffineTransform qt_transform_from_fontdef(const QFontDef &fontDef)
Q_GUI_EXPORT bool qt_scaleForTransform(const QTransform &transform, qreal *scale)
static void qcoretextfontengine_scaleMetrics(glyph_metrics_t &br, const QTransform &matrix)
static void convertCGPathToQPainterPath(void *info, const CGPathElement *element)
#define COMPARE_WEIGHT_DISTANCE(ct_weight, qt_weight)
CGAffineTransform Q_GUI_EXPORT qt_transform_from_fontdef(const QFontDef &fontDef)
#define MAKE_TAG(ch1, ch2, ch3, ch4)
void qGamma_correct_back_to_linear_cs(QImage *image)
#define qCWarning(category,...)
#define qCDebug(category,...)
constexpr T qAbs(const T &t)
GLsizei const GLfloat * v
[13]
GLint GLint GLint GLint GLint x
[0]
GLint GLsizei GLsizei height
GLenum GLuint GLenum GLsizei length
GLenum const void GLbitfield GLsizei numGlyphs
GLsizei GLsizei GLfloat distance
GLint GLsizei GLsizei GLenum format
GLenum GLsizeiptr const void * fontData
GLuint GLenum GLenum transform
GLsizei const GLchar *const * path
GLenum GLenum GLenum GLenum GLenum scale
GLenum GLenum GLsizei void * table
Q_GUI_EXPORT bool qt_scaleForTransform(const QTransform &transform, qreal *scale)
struct CGContext * CGContextRef
QT_BEGIN_NAMESPACE typedef unsigned int QRgb
constexpr int qRed(QRgb rgb)
constexpr int qGreen(QRgb rgb)
constexpr int qGray(int r, int g, int b)
constexpr int qBlue(QRgb rgb)
Q_CORE_EXPORT bool qEnvironmentVariableIsSet(const char *varName) noexcept
QFileInfo info(fileName)
[8]
QFile defaults(defaultsPath)
ConvertPathInfo(QPainterPath *newPath, const QPointF &newPos, qreal newStretch=1.0)
static constexpr QFixed fromReal(qreal r)
constexpr int toInt() const
constexpr QFixed ceil() const
constexpr qreal toReal() const
constexpr int truncate() const