15#include "kstarsdata.h"  
   17#include "projections/projector.h" 
   23typedef struct LabelRun
 
   25    LabelRun(
int s, 
int e) : start(s), end(e) {}
 
   40        pinstance = 
new SkyLabeler();
 
   47    QFont font(m_p.font());
 
   49    QFont font(m_stdFont);
 
   52    if (Options::zoomFactor() < 2.0 * MINZOOM)
 
   54    else if (Options::zoomFactor() < 10.0 * MINZOOM)
 
   68    if (m_drawFont.pointSize() != font.
pointSize())
 
 
   77    double offset = 
dms::PI * Options::zoomFactor() / 10800.0 / 3600.0;
 
   78    return 4.0 + offset * 0.5;
 
 
   83SkyLabeler::SkyLabeler()
 
   84    : m_fontMetrics(
QFont()), m_picture(-1), labelList(NUM_LABEL_TYPES)
 
  100SkyLabeler::~SkyLabeler()
 
  102    for (
auto &row : screenRows)
 
  104        for (
auto &item : *row)
 
  115    qreal h = m_fontMetrics.height();
 
  116    qreal w = m_fontMetrics.averageCharWidth() * text.
size();
 
  117    qreal s = sin(angle * 
dms::PI / 180.0);
 
  118    qreal c = cos(angle * 
dms::PI / 180.0);
 
  122    qreal top, bot, left, right;
 
  127        top   = o.
y() - s * w2;
 
  128        bot   = o.
y() + c * h + s * w2;
 
  129        left  = o.
x() - c * w2 - s * h;
 
  130        right = o.
x() + c * w2;
 
  134        top   = o.
y() + s * w2;
 
  135        bot   = o.
y() + c * h - s * w2;
 
  136        left  = o.
x() - c * w2;
 
  137        right = o.
x() + c * w2 - s * h;
 
  155    m_p.drawText(
QPointF(-w2, h), text);
 
 
  162                               const qreal padding_factor)
 
  169    QPointF p(_p.
x() + offset, _p.
y() + offset);
 
  171    if (!
markText(p, sLabel, padding_factor))
 
  177        double factor       = log(Options::zoomFactor() / 750.0);
 
  178        double newPointSize = qBound(12.0, factor * m_stdFont.pointSizeF(), 18.0) * (1.0 + 0.7 * Options::labelFontScaling()/100.0);
 
  179        QFont zoomFont(m_p.font());
 
  181        m_p.setFont(zoomFont);
 
  182        m_p.drawText(p, sLabel);
 
 
  209    QFont font(m_p.font());
 
  211    QFont font(m_drawFont);
 
 
  229    float height     = m_fontMetrics.height();
 
  230    float width      = m_fontMetrics.averageCharWidth() * text.
size();
 
  231    float sideMargin = m_fontMetrics.averageCharWidth() * 2 + width / 2.0;
 
  237    winHeight = SkyMapLite::Instance()->height();
 
  238    winWidth  = SkyMapLite::Instance()->width();
 
  240    winHeight = m_p.window().height();
 
  241    winWidth  = m_p.window().width();
 
  244    *right = winWidth - sideMargin;
 
  247    *bot   = winHeight - 2.0 * height;
 
 
  258    m_p.begin(&m_picture);
 
  261    m_p.drawPoint(skyMap->
width() + 1, skyMap->
height() + 1);
 
  264    m_stdFont = 
QFont(m_p.font());
 
  266    m_skyFont     = m_p.font();
 
  268    m_minDeltaX   = (int) m_fontMetrics.averageCharWidth() * 5;
 
  274    m_yScale = (m_fontMetrics.height() + 1.0);
 
  276    int maxY = int(skyMap->
height() / m_yScale);
 
  280    int m_maxX = skyMap->
width();
 
  281    m_size     = (maxY + 1) * m_maxX;
 
  286        screenRows.resize(m_maxY);
 
  287        for (
int y = m_maxY; y <= maxY; y++)
 
  289            screenRows.append(
new LabelRow());
 
  296    int minMaxY = (maxY < m_maxY) ? maxY : m_maxY;
 
  298    for (
int y = 0; y <= minMaxY; y++)
 
  300        LabelRow *row = screenRows[y];
 
  302        for (
auto &item : *row)
 
  314    m_marks = m_hits = m_misses = m_elements = 0;
 
  317    for (
auto &item : labelList)
 
 
  332    m_skyFont     = m_drawFont;
 
  334    m_minDeltaX   = (int)m_fontMetrics.width(
"MMMMM");
 
  339    m_yScale = (m_fontMetrics.
height() + 1.0);
 
  341    int maxY = int(skyMap->
height() / m_yScale);
 
  345    int m_maxX = skyMap->
width();
 
  346    m_size     = (maxY + 1) * m_maxX;
 
  351        screenRows.resize(m_maxY);
 
  352        for (
int y = m_maxY; y <= maxY; y++)
 
  354            screenRows.append(
new LabelRow());
 
  361    int minMaxY = (maxY < m_maxY) ? maxY : m_maxY;
 
  363    for (
int y = 0; y <= minMaxY; y++)
 
  365        LabelRow *row = screenRows[y];
 
  366        for (
int i = 0; i < row->
size(); i++)
 
  378    m_marks = m_hits = m_misses = m_elements = 0;
 
  381    for (
int i = 0; i < labelList.size(); i++)
 
  383        labelList[i].clear();
 
  410    static const auto ramp_zoom = log10(MAXZOOM) + log10(0.3);
 
  412    if (padding_factor != 1)
 
  415            (1 - ((std::min(log10(Options::zoomFactor()), ramp_zoom)) / ramp_zoom)) *
 
  420    const qreal maxX = p.
x() + m_fontMetrics.averageCharWidth() * text.
size() * padding_factor;
 
  421    const qreal minY = p.
y() - m_fontMetrics.height() * padding_factor;
 
 
  430            qDebug() << Q_FUNC_INFO << 
QString(
"Someone forgot to reset the SkyLabeler!");
 
  435    int minX = int(left);
 
  436    int maxX = int(right);
 
  444    int maxY = int(bot / m_yScale);
 
  445    int minY = int(top / m_yScale);
 
  465    for (
int y = minY; y <= maxY; y++)
 
  467        LabelRow *row = screenRows[y];
 
  469        for (i = 0; i < row->
size(); i++)
 
  471            if (row->
at(i)->end < minX)
 
  473            if (row->
at(i)->start > maxX)
 
  481    m_marks += (maxX - minX + 1) * (maxY - minY + 1);
 
  486    for (
int y = minY; y <= maxY; y++)
 
  488        LabelRow *row = screenRows[y];
 
  493            row->
append(
new LabelRun(minX, maxX));
 
  501        for (i = 0; i < row->
size(); i++)
 
  503            if (row->
at(i)->end >= minX)
 
  512            if (row->
at(0)->start - maxX < m_minDeltaX)
 
  514                row->
at(0)->start = minX;
 
  518                row->
insert(0, 
new LabelRun(minX, maxX));
 
  525        else if (i == row->
size())
 
  527            if (minX - row->
at(i - 1)->end < m_minDeltaX)
 
  529                row->
at(i - 1)->end = maxX;
 
  533                row->
append(
new LabelRun(minX, maxX));
 
  542        bool mergeHead = (minX - row->
at(i - 1)->end < m_minDeltaX);
 
  543        bool mergeTail = (row->
at(i)->start - maxX < m_minDeltaX);
 
  546        if (mergeHead && mergeTail)
 
  548            row->
at(i - 1)->end = row->
at(i)->end;
 
  557            row->
at(i - 1)->end = maxX;
 
  563            row->
at(i)->start = minX;
 
  569            row->
insert(i, 
new LabelRun(minX, maxX));
 
 
  579    bool visible = 
false;
 
  580    QPointF p    = m_proj->toScreen(obj, 
true, &visible);
 
  583    labelList[(int)type].append(SkyLabel(p, obj));
 
 
  589    labelList[(int)type].append(SkyLabel(pos, obj));
 
  601    if (labelList[SATURN_MOON_LABEL].size() > 0)
 
  608    if (labelList[JUPITER_MOON_LABEL].size() > 0)
 
  625    LabelList list = labelList[RUDE_LABEL];
 
  627    for (
const auto &item : list)
 
 
  635    LabelList list = labelList[type];
 
  637    for (
const auto &item : list)
 
 
  651    QRectF rect    = m_p.fontMetrics().boundingRect(sLabel);
 
  652    rect.
moveTo(p.
x() + offset, p.
y() + offset);
 
  661    QColor color(KStarsData::Instance()->colorScheme()->colorNamed(
"SkyColor"));
 
  662    color.
setAlpha(m_p.pen().color().alpha()); 
 
  663    m_p.fillRect(rect2, 
QBrush(color));
 
  664    m_p.drawText(rect.
topLeft(), sLabel);
 
 
  673    return 100.0 * float(m_marks) / float(m_size);
 
 
  680    return 100.0 * float(m_hits) / (float(m_hits + m_misses));
 
 
  685    printf(
"SkyLabeler:\n");
 
  686    printf(
"  fillRatio=%.1f%%\n", 
fillRatio());
 
  687    printf(
"  hits=%d  misses=%d  ratio=%.1f%%\n", m_hits, m_misses, 
hitRatio());
 
  688    printf(
"  yScale=%.1f maxY=%d\n", m_yScale, m_maxY);
 
  690    printf(
"  screenRows=%d elements=%d virtualSize=%.1f Kbytes\n", screenRows.size(), m_elements,
 
  691           float(m_size) / 1024.0);
 
 
QColor colorNamed(const QString &name) const
Retrieve a color by name.
 
KStarsData is the backbone of KStars.
 
ColorScheme * colorScheme()
 
The purpose of this class is to prevent labels from overlapping.
 
float fillRatio()
diagnostic.
 
bool markText(const QPointF &p, const QString &text, qreal padding_factor=1)
tells the labeler the location and text of a label you want to draw.
 
void resetFont()
sets the font in SkyLabeler and in psky back to the zoom dependent value that was set in reset().
 
void shrinkFont(int delta)
decreases the size of the font in psky and in the SkyLabeler by the delta points.
 
void setZoomFont()
adjusts the font in psky to be smaller if we are zoomed out.
 
bool markRegion(qreal left, qreal right, qreal top, qreal bot)
Works just like markText() above but for an arbitrary rectangular region bounded by top,...
 
void drawQueuedLabels()
draws the labels stored in all the buffers.
 
void setFont(const QFont &font)
tells the labeler the font you will be using so it can figure out the height and width of the labels.
 
void reset(SkyMap *skyMap)
clears the virtual screen (if needed) and resizes the virtual screen (if needed) to match skyMap.
 
void getMargins(const QString &text, float *left, float *right, float *top, float *bot)
sets four margins for help in keeping labels entirely on the screen.
 
bool drawGuideLabel(QPointF &o, const QString &text, double angle)
Tries to draw the text at the position and angle specified.
 
void addLabel(SkyObject *obj, label_t type)
queues the label in the "type" buffer for later drawing.
 
void setPen(const QPen &pen)
sets the pen used for drawing labels on the sky.
 
static double ZoomOffset()
returns the zoom dependent label offset.
 
float hitRatio()
diagnostic, the number of times mark() returned true divided by the total number of times mark was ca...
 
void useStdFont()
sets the font in SkyLabeler and in psky to the font psky had originally when reset() was called.
 
void printInfo()
diagnostic, prints some brief statistics to the console.
 
void drawQueuedLabelsType(SkyLabeler::label_t type)
a convenience routine that draws all the labels from a single buffer.
 
void draw(QPainter &p)
KStars Lite version of the function above.
 
void drawRudeNameLabel(SkyObject *obj, const QPointF &_p)
draw the object's name label on the map, without checking for overlap with other labels.
 
bool drawNameLabel(SkyObject *obj, const QPointF &_p, const qreal padding_factor=1)
Tries to draw a label for an object.
 
This is the main item that displays all SkyItems.
 
const Projector * projector() const
Get the current projector.
 
This is the canvas on which the sky is painted.
 
const Projector * projector() const
Get the current projector.
 
Provides all necessary information about an object in the sky: its coordinates, name(s),...
 
QString translatedName() const
 
virtual QString labelString() const
 
virtual double labelOffset() const
 
static constexpr double PI
PI is a const static member; it's public so that it can be used anywhere, as long as dms....
 
int pointSize() const const
 
void setPointSize(int pointSize)
 
void setPointSizeF(qreal pointSize)
 
qreal height() const const
 
void append(QList< T > &&value)
 
const_reference at(qsizetype i) const const
 
iterator insert(const_iterator before, parameter_type value)
 
void removeAt(qsizetype i)
 
qsizetype size() const const
 
qreal height() const const
 
void moveTo(const QPointF &position)
 
void setHeight(qreal height)
 
QPointF topLeft() const const
 
bool isEmpty() const const
 
qsizetype size() const const