191 lines
5.2 KiB
C++
191 lines
5.2 KiB
C++
|
|
#include "uipriv_qt5.hpp"
|
|
|
|
#include "draw.hpp" // draw context
|
|
|
|
#include <QFontDatabase>
|
|
#include <QFontMetricsF>
|
|
#include <QTextLayout>
|
|
|
|
struct uiDrawFontFamilies : public QStringList
|
|
{
|
|
uiDrawFontFamilies(const QStringList &stringList)
|
|
: QStringList(stringList) {}
|
|
};
|
|
|
|
struct uiDrawTextLayout : public QTextLayout
|
|
{
|
|
uiDrawTextLayout(const QString& text, const QFont &font, double width)
|
|
: QTextLayout(text, font)
|
|
, width_(width)
|
|
{
|
|
// qWarning("TODO: figure out wtf width is for: %f", width_);
|
|
}
|
|
double width_ = 0.0;
|
|
};
|
|
|
|
uiDrawFontFamilies *uiDrawListFontFamilies(void)
|
|
{
|
|
return new uiDrawFontFamilies(QFontDatabase().families());
|
|
}
|
|
|
|
uintmax_t uiDrawFontFamiliesNumFamilies(uiDrawFontFamilies *ff)
|
|
{
|
|
return ff->count();
|
|
}
|
|
|
|
char *uiDrawFontFamiliesFamily(uiDrawFontFamilies *ff, uintmax_t n)
|
|
{
|
|
return uiQt5StrdupQString(ff->value(n));
|
|
}
|
|
|
|
void uiDrawFreeFontFamilies(uiDrawFontFamilies *ff)
|
|
{
|
|
delete ff;
|
|
}
|
|
|
|
static int uiDrawTextWeightToFontWeight(uiDrawTextWeight weight)
|
|
{
|
|
switch (weight)
|
|
{
|
|
case uiDrawTextWeightThin: return QFont::Thin;
|
|
case uiDrawTextWeightUltraLight: return QFont::ExtraLight;
|
|
case uiDrawTextWeightLight: return QFont::Light;
|
|
case uiDrawTextWeightBook: return (QFont::Light+QFont::Normal)/2;
|
|
case uiDrawTextWeightNormal: return QFont::Normal;
|
|
case uiDrawTextWeightMedium: return QFont::Medium;
|
|
case uiDrawTextWeightSemiBold: return QFont::DemiBold;
|
|
case uiDrawTextWeightBold: return QFont::Bold;
|
|
case uiDrawTextWeightUtraBold: return QFont::ExtraBold;
|
|
case uiDrawTextWeightHeavy: return (QFont::ExtraBold+QFont::Black)/2;
|
|
case uiDrawTextWeightUltraHeavy: return QFont::Black;
|
|
default:
|
|
qWarning("Unknown uiDrawTextWeight: %d", weight);
|
|
}
|
|
return QFont::Normal;
|
|
}
|
|
|
|
static int uiDrawTextItalicToFontStyle(uiDrawTextItalic italic)
|
|
{
|
|
switch(italic)
|
|
{
|
|
case uiDrawTextItalicNormal: return QFont::StyleNormal;
|
|
case uiDrawTextItalicOblique: return QFont::StyleOblique;
|
|
case uiDrawTextItalicItalic: return QFont::StyleItalic;
|
|
default:
|
|
qWarning("Unknown uiDrawTextItalic: %d", italic);
|
|
}
|
|
return QFont::StyleNormal;
|
|
}
|
|
|
|
static int uiDrawTextStretchToFont(uiDrawTextStretch stretch)
|
|
{
|
|
switch(stretch)
|
|
{
|
|
case uiDrawTextStretchUltraCondensed: return QFont::UltraCondensed;
|
|
case uiDrawTextStretchExtraCondensed: return QFont::ExtraCondensed;
|
|
case uiDrawTextStretchCondensed: return QFont::Condensed;
|
|
case uiDrawTextStretchSemiCondensed: return QFont::SemiCondensed;
|
|
case uiDrawTextStretchNormal: return QFont::Unstretched;
|
|
case uiDrawTextStretchSemiExpanded: return QFont::SemiExpanded;
|
|
case uiDrawTextStretchExpanded: return QFont::Expanded;
|
|
case uiDrawTextStretchExtraExpanded: return QFont::ExtraExpanded;
|
|
case uiDrawTextStretchUltraExpanded: return QFont::UltraExpanded;
|
|
default:
|
|
qWarning("Unknown uiDrawTextStretch: %d", stretch);
|
|
}
|
|
return QFont::Unstretched;
|
|
}
|
|
|
|
uiDrawTextFont *uiDrawLoadClosestFont(const uiDrawTextFontDescriptor *desc)
|
|
{
|
|
QFont font(QString::fromUtf8(desc->Family));
|
|
font.setPointSizeF(desc->Size);
|
|
font.setWeight(uiDrawTextWeightToFontWeight(desc->Weight));
|
|
font.setItalic(uiDrawTextItalicToFontStyle(desc->Italic));
|
|
font.setStretch(uiDrawTextStretchToFont(desc->Stretch));
|
|
|
|
return new uiDrawTextFont(font);
|
|
}
|
|
|
|
void uiDrawFreeTextFont(uiDrawTextFont *font)
|
|
{
|
|
delete font;
|
|
}
|
|
|
|
uintptr_t uiDrawTextFontHandle(uiDrawTextFont *font)
|
|
{
|
|
qWarning("TODO: %p", (void *)font);
|
|
return 0;
|
|
}
|
|
|
|
void uiDrawTextFontDescribe(uiDrawTextFont *font, uiDrawTextFontDescriptor *desc)
|
|
{
|
|
qWarning("TODO: %p %p", (void *)font, (void *)desc);
|
|
}
|
|
|
|
void uiDrawTextFontGetMetrics(uiDrawTextFont *font, uiDrawTextFontMetrics *metrics)
|
|
{
|
|
if (font) {
|
|
QFontMetricsF fontMetrics(*font);
|
|
metrics->Ascent = fontMetrics.ascent();
|
|
metrics->Descent = fontMetrics.descent();
|
|
metrics->Leading = fontMetrics.leading();
|
|
metrics->UnderlinePos = fontMetrics.underlinePos();
|
|
metrics->UnderlineThickness = 0; // TODO?
|
|
}
|
|
}
|
|
|
|
uiDrawTextLayout *uiDrawNewTextLayout(const char *text, uiDrawTextFont *defaultFont, double width)
|
|
{
|
|
return new uiDrawTextLayout(QString::fromUtf8(text), *defaultFont, width);
|
|
}
|
|
|
|
void uiDrawFreeTextLayout(uiDrawTextLayout *layout)
|
|
{
|
|
delete layout;
|
|
}
|
|
|
|
void uiDrawTextLayoutSetWidth(uiDrawTextLayout *layout, double width)
|
|
{
|
|
layout->width_ = width;
|
|
}
|
|
|
|
static void runLayouting(uiDrawTextLayout *layout)
|
|
{
|
|
layout->setCacheEnabled(true);
|
|
layout->beginLayout();
|
|
forever {
|
|
QTextLine line = layout->createLine();
|
|
if (!line.isValid()) {
|
|
break;
|
|
}
|
|
// TODO: shift by line height?
|
|
}
|
|
layout->endLayout();
|
|
}
|
|
|
|
void uiDrawTextLayoutExtents(uiDrawTextLayout *layout, double *width, double *height)
|
|
{
|
|
runLayouting(layout);
|
|
auto boundingRect = layout->boundingRect();
|
|
*width = boundingRect.width();
|
|
*height = boundingRect.height();
|
|
}
|
|
|
|
void uiDrawText(uiDrawContext *c, double x, double y, uiDrawTextLayout *layout)
|
|
{
|
|
runLayouting(layout);
|
|
layout->draw(c, {x,y});
|
|
}
|
|
|
|
void uiDrawTextLayoutSetColor(uiDrawTextLayout *layout, intmax_t startChar, intmax_t endChar, double r, double g, double b, double a)
|
|
{
|
|
// ineffective..? but works
|
|
auto additionalFormats = layout->additionalFormats();
|
|
QTextCharFormat format;
|
|
format.setForeground(QColor::fromRgbF(r,g,b,a));
|
|
additionalFormats.append(QTextLayout::FormatRange{(int)startChar,(int)(1+endChar-startChar),format});
|
|
layout->setAdditionalFormats(additionalFormats);
|
|
}
|